Apply Atom theme to iframe?

My package includes an HTML file in a pane item via iframe, and I would like to style elements within that iframe according to the current Atom theme. The problem is:

  • I can style by linking to a CSS file within the HTML file, but that does not allow to use theme variables.

  • I can put a LESS file in the package’s styles directory so that it gets compiled, and I can use theme variables in it, but linking to that file within the HTML file doesn’t work.

I found that I can obtain the LESS-compiled-into-CSS by

css = document.querySelector(
        `style[source-path$="mypackage/styles/mystyle.less"]`
      ).innerText

and then inject it into the iframe by

myiframe.contentDocument.getElementById('dummystyle').innerText = css

where dummystyle is the HTML ID of an empty <style> element.

This works, but is rather hacky. Is there a better way?

First of all: do you really need to use an iFrame? What about using insertAdjacentHTML or other document methods to create your HTML?

Otherwise, I don’t find your implementation that hacky. I’d probably use an event handler that makes use of postMessage. That way you can update the iFrame styles whenever a user changes the theme.

First of all: do you really need to use an iFrame? What about using insertAdjacentHTML 1 or other document methods to create your HTML?

Yes, I do. It’s not about creating the HTML, it’s about isolation from the main document tree, as well as other instances.

Otherwise, I don’t find your implementation that hacky.

Good, thanks! I called it hacky because it involves using an aspect of Atom that isn’t part of the API. And I would have thought that there is a proper way to access LESS-compiled-to-CSS.

I’d probably use an event handler that mKes use postMessage 1. That way you can update the iFrame styles whenever a user changes the theme.

I use atom.themes.onDidChangeActiveThemes for that.

I found another way to get a LESS file compiled:

css = atom.themes.loadLessStylesheet(lessFile)

I like this better, because its avoids inserting a stylesheet into Atom that is only intended for the iframe.

It is still “hacky” because loadLessStylesheet is not documented at ThemeManager.

I really, really wish Atom was better documented. Atom really is a “hackable text editor”, not a programmable or configurable one. Anything beyond the simplest things is doomed to break sooner or later. :cold_sweat:

I’m developing packages for Sublime Text, VSCode and Atom and I actually think the latter is not only the best documented out of those three, but also has the most powerful API.

Oh no doubt. It’s just that if I’m thinking of API documentation, something like this comes to mind…