Allow the user to generate cards without client-side JavaScript (was: HTML-only social cards)
Closed this issue · 8 comments
MementoEmbed relies upon the JavaScript file mementoembed.js
to populate and format a social card based on data-*
elements. This enhancement request seeks to provide a pre-made version of the social card without the JavaScript. It would still retain the data-*
elements for compatibility with other tools like RobustLinks.
If possible, it would be nice for the social card format to be specified in one place. This will mitigate problems caused by duplication. I do not currently have an idea of how to do this cleanly.
Experiments last weekend with node
indicate that no document object exists in the node environment by default, hence merely executing our existing JavaScript library and returning the output will not be easy without potentially a full browser. I'm not crazy about that solution because it will impact performance.
Alternatively, we can just ensure that we capture the HTML as we make changes to the JavaScript file. This seems error prone, but may be the only way to achieve this functionality in the short term.
What details are not available at the time of card generation that would require a full browser execution environment to realize them?
The styles are currently embedded in the existing JavaScript file.
You are leading me to consider an interesting concept, @ibnesayeed . Perhaps that JavaScript file needs to be "template" of its own, with the styles generated elsewhere and then inserted into the final product. CSS and JavaScript use different syntax for styles, which could make sharing styles difficult between the JavaScript and HTML-only versions of cards.
I'm brainstorming ways MementoEmbed could support:
- a compact HTML format referencing a JavaScript resource (current implementation)
- a verbose HTML-only social card with all styles embedded
That is very doable. I think you might want to read about the well-supported Template literals (if you haven't already) that works in major browsers as well as in Node. More interesting bit for you would be tagged templates in it. In fact there is a small templating library lit-html that is based on this capability, though you don't need it here, but it would be useful to learn about it nonetheless.
So, with that, here is how I think we can carry this out:
- Create a simple, light-weight, style-free, but expressive and easy to parse snippet (the current implementation) and make sure that the format of it will not change very often in the future. This will have only the basic rendering capabilities that preserves and shows necessary data without worrying too much about styles.
- Create a JavaScript function to parse that compact markup and return a structured object from it.
- Create an extended template (using tagged template literal syntax) with all the necessary styles and markup to yield a robust render-ready markup. This can be modified in future without altering the compact data-provider markup.
- Create the tag function that will be called when evaluating the template. This function will fill in the details using the object returned from the parser function.
With this structure, you can embed just the compact data markup and a JS file that includes the remaining three components and some logic to replace the DOM node after populating the template.
And the alternative means would be to perform template population in Node using the same workflow and code and yield a script-free pre-baked markup for embedding.
After reading your description, I discovered the jsdom library that fills in the missing functionality that I was looking for. Thanks for the inspiration and the proposed solution. I believe I have a path forward.
If you are planning to work along the lines of what I outlined then you might not even need any DOM parsing libraries (though it won't hurt to have one to use on server side). If your compact markup is stable enough and not going to change very often then you can have a custom parser (instead of a heavy general purpose DOM parser) for it to extract out details from it. Also, DOM interaction will be available if you were to execute JS in the browser context, and on the server side you might not even need to parse compact markup as the data that you might extract from it is already available when you generated it.
The machine API part of this task is complete. The UI part appears to have some issues in Safari. I will have to reconsider how I am generating the cards on the UI side. I'm considering getting rid of the nice status interface.
This was addressed in a recent code update.