ankit / stylebot

Change the appearance of the web instantly
https://stylebot.dev/
MIT License
1.41k stars 208 forks source link

[Bug] Styles are not applied to iframes with src='about:blank' #743

Open dan-robertson opened 1 year ago

dan-robertson commented 1 year ago

Describe the bug

iframes may be created with no src attribute, which implies the same as src="about:blank", and then dynamically have content added to them by javascript. For example, this is how TinyMCE works. The stylebot content script is not added to such iframes. I think this is a bug and it is desirable for stylebot to work in them.

Browser

Google Chrome 109.0.5414.119 on MacOS. But I’ve seen the same bug on Linux too.

To Reproduce

Here is a small html page which exhibits the bug, temp.html:

<html>
  <h1 name='h'>On page</h1>
  <iframe name="i1" src="temp.html"></iframe>
  <iframe name="i2"></iframe>
  <script>
    if (window === window.top){
        function add_elem(window, text) {
            window.document.open();
            window.document.write('<h1>In ' + text +'</h1>');
            window.document.close();
        }
        add_elem(i2.window, 'i2');
        i3 = document.createElement('iframe');
        document.body.appendChild(i3);
        add_elem(i3.contentWindow, 'i3');
    } else {
        document.body.innerHTML = '<h1>in i1</h1>'
    }
  </script>
</html>

This gives you:

Add a simple stylebot rule to apply to all URLs like:

h1 {
  color: blue;
}

Now load the html page (if the page is stored locally, you need to allow the extension for file urls).

Expected behavior

All <h1> elements should be blue

Actual behavior

Only some <h1> elements are blue

Screenshots

Screenshot 2023-02-01 at 23 15 49

Additional context

So the first thing is I think it is necessary to modify the content_scripts section of the manifest to have match_about_blank set to true for the inject-css script. According to the docs, this should cause the script to be injected into these frames.

I’m not sure that that’s sufficient, however. I’m not sure that inject-css/index.ts:55 will work correctly if the src is about:blank. I tried reading this value in the chrome console and got the url for the toplevel window so maybe I’m wrong and this doesn’t need changing. I also don’t know how well the style injection will work with the outer window dynamically changing the contents of the iframes – maybe that will stomp on any css that is injected.

joewelds commented 1 year ago

Same issue here. Trying to target iframes worked a couple times, but not always.