Grid layout after content iframe resize
Sorry in advance if I talk about stuff you guys already know. That stuff is still relatively new to me.
This started with me wanting to write a bot to publish content from The Next Platform (TNP from here on). I soon noticed that oembeds from that site were not showing. After a few trials and errors, I settle on defining a
content/previews.py. Side note: a user-agent is missing only if AutoDiscovery is used.
That change allowed the rendering of oembeds from TNP, but the rendered height was wrong. After spending a number of hours trying to work around CORS to access the iframe's inner content height, I gave up. The way TNP (and I suspect many other sites, and most likely all WordPress sites) deals with height changes is by listening to a message event that is expected to come from a script running from within the iframe.
I also learned that scripts loaded by assigning content to innerHTML don't run. Since TNP's script listening to message events is set in content.rendered, and that Vue sets the content through innerHTML, the height update messages are falling to devnull.
Taking example from the existing Twitter hack, I tried to work around this by adding that script to
stream/templates/stream/includes to make sure it would already have been loaded when the grid starts filling up. At that point, the height was still not updated within the grid, but progress was made as it was now successfully updated when displaying a single post (by clicking on the timestamp for example). The main issue was that it is expected the iframe src attribute will be updated with a randomly generated token that is to be sent back by the inner script to ensure the proper iframe height is updated. Since this update relies on the
DOMContentLoaded event, it seems it can't happen from the grid layout process. So I now generate this token from
content/previews.py (and the corresponding data-secret attribute TNP uses) and add it to the iframe tag. I also remove the script and the blockquote (but that one is just a matter of taste) TNP sends.
Finally, I came up with a working solution by using a
MutationObserver on iframe height and style from a new
StreamElement component method. Why listening to style changes? I found out the two
setTimeout calls in
layoutAfterTwitterOembeds could be replaced with that observer.
That's about it for this PR. I hope I'm making some sense. Looking forward to hear your thoughts about this. I feel like this was a lot of work just for a single site's oembeds (but I had fun doing it