firenvim icon indicating copy to clipboard operation
firenvim copied to clipboard

Ideal route to take to tweak the position of the iframe on the page?

Open MostHated opened this issue 1 year ago • 2 comments

Hey there, This is more of a general request for guidance than an issue, but I was hoping you might be able to point me in the right direction? I am wanting to make some persistent tweaks to the postion of the iframe overlay, at least on my most frequent places I use it, ex, right here in this comment box.

My usual go-to is to use the addon Stylus and just fine the appropriate css selectors/path, save it in Stylus and I am good to go, usually forever. The issue with that seems to be, it does it's thing way too early as the page is loading, and the iframe doesn't exist yet.

My next thought was to use TamperMonkey to see if I could do some sort of delayed search for the iframe upon detecting that the text area was clicked, then trying to get the iframe from that point. Unfortunately, I am not a web guy, and I barely know any sort of "Dom" related things. Javascript is probably my least used language.

That said, I did make an attempt, at least and was able to get the click event, but have yet to be able to programatically locate the iframe element to make the position adjustments, so my next idea was trying to see if there was something I could expose/add to the plugin itself to allow for either more easily finding, or making positional tweaks without having to do all the extra stuff. So my question is, if I were to do something like that, where might be the recommended place to start, from a code perspective? I am guessing that there must be some sort of event emitted somewhere when the iframe is loading, so perhaps if I were able to add an additional one that I can use, and the add somethihng like an nvim attribute to the iframe to keep track of them, perhaps that could at least be a start.

I am sure that this whole thing seems quite unecessary to most people to simply move a box a few pixels, but sadly, I have spent much longer for much less just to appease my OCD tendencies, lol.

Thanks, -MH

MostHated avatar Mar 03 '23 04:03 MostHated

Hi! Thanks for describing the various things you tried, despite them not working out it's great to see that you spent some time/effort solving this on your own before opening an issue :)

Firenvim tries very hard to hide and protect itself from the page, which is why you're having a hard time getting CSS from the page/other extensions to apply to the Firenvim frame. The only solution I can think of is to create a new url-specific Firenvim setting that would enable users to customize the CSS that is applied to the Firenvim frame. This setting would be at risk of clobbering some of the CSS settings Firenvim computes on its own and that are required for operating correctly though (e.g. the frame is placed over textareas through CSS), so I'm not quite sure what the right solution would be. I need to think about this some more :)

glacambre avatar Mar 03 '23 06:03 glacambre

Just for some additional context, here is how the frame is currently:

Then, this is what I am attempting to acheive:

Then here are some snippets from the userscript I was playing around with:

let commentField = document.getElementById("new_comment_field")

function clickHandler() {
  console.log("Clicked")

  let spanItem = document.querySelectorAll("span")
  console.log('Found spans: ' + spanItem.length);

  for (let i = 0; i < spanItem.length; i++) {
    if (spanItem[i].tabIndex === -1) {

      // Adding this was just for my own sanity, 
      // to make sure at least *something* was working
      spanItem[i].setAttribute("nvim", true)
      
      let frame = spanItem[i].querySelector('iframe');

      // Just a test to see what happens/if it works -
      // Spoiler: it doesn't -------------------------
      if (frame){
        let leftStyle = frame.style.left;
        frame.style.left = leftStyle + "50px"; 
      }

      // Operation not permitted, it seems
      // ---------------------------------
      const shadow = spanItem[i].attachShadow({
        mode: 'open',
        delegatesFocus: true
      });

      if (shadow) {
        console.log("Found shadow!")
        let frame = shadow.firstChild;
        if (frame) {
          console.log("Found frame!")
          frame.setAttribute("nvim", true)
        }
      }

      // Doesn't work either ---------------
      if (spanItem[i].shadowRoot) {
        console.log("Found shadow root!")
        let frame = spanItem[i].shadowRoot.querySelector('iframe');
        console.log('Found frame: ' + spanItem[i].shadowRoot.querySelector('iframe'));
        if (frame) {
          console.log("Found frame!")
          frame.addEventListener("load", function () {
            console.log("Loaded!");
            frame.setAttribute("nvim", true)
          });
        }
      }
    }
  }

  // Something I found on a forum, but it doesn't work either
  // waitForKeyElements("iframe, frame", function (elem) {
  //   console.log("Found iframe!")
  //   elem.addEventListener("load", function () {
  //     console.log("Loaded!");
  //     elem.setAttribute("nvim")
  //   });
  // });
}

// Detect when the mouse has been clicked within the comment field
if (commentField) {
  console.log("Found comment field")
  commentField.addEventListener("click", function () {
    setTimeout(clickHandler, 2000);
  }, false);
}

MostHated avatar Mar 03 '23 18:03 MostHated