0

I have been trying to create a GeckoView based web extension for downloading images on my facebook mobile feed. So as a first run, I used Inspect> console in google chrome to test a simple script to detect all images and make the border red:

var imgs=document.getElementsByTagName("img");
for (i=0;i<imgs.length;i++)
{
imgs[i].style.border="3px solid red";
}  

The above lines of code work perfectly well in google chrome console for a number of websites (including facebook). However when I package the JS code as a content script for geckoview web extension, it simply fails to work ! Here are all the tricks I have tried so far:

  1. Making sure that the content_script is loaded AFTER the document by including:

      "content_scripts": [{
           "run_at": document_end,
          "js": ["myscript.js"],
          "matches": ["<all_urls>"],
          "match_about_blank": true,
          "all_frames": true }]
    

    Also tried: "run_at": document_idle.

  2. Making sure that 'x-ray' vision is off by using document.wrappedJSObject.getElementsByTagName("img")

  3. Unregistering and re-registering web extension.

None of this worked. Interestingly, the web extension works on all other websites except facebook ! So I am suspecting I have one of the two problems:

  1. Facebook has done a really great job hiding their DOM !
  2. GeckoView cannot access DOM for "dynamically generated" image elements.

Any help would be appreciated :)

Greg
  • 1
  • First of use the API. Secondly yes Facebook does not allow it and therefor does not make it easy for you. And what every you make will most likely break in a few days. – WizKid Feb 11 '20 at 18:30
  • If the google chrome console is able to detect image tags, it should be possible for extensions too. I am not using their API as I want to make my extension and app independent of facebook. – Greg Feb 11 '20 at 21:24
  • Sure you can. Facebook just do it hard for you – WizKid Feb 11 '20 at 21:32

1 Answers1

1

I just tested it and the extension as written works for me. The code you wrote will only catch images that are preset on the page at load time, but much of the Facebook website is loaded dynamically after that, which is probably why you're not seeing the border added to most images.

You need a way to observe changes to the DOM and catch all new images added dynamically for this to work the way you intend to. E.g. using MutationObserver: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver

function observe() {
  var imgs = document.getElementsByTagName("img");
  for (i = 0; i < imgs.length; i++) {
    imgs[i].style.border="3px solid red";
  }
}

// Select the node that will be observed for mutations
const targetNode = document.body;

// Options for the observer (which mutations to observe)
const config = { attributes: true, childList: true, subtree: true };

// Create an observer instance linked to the callback function
const observer = new MutationObserver(observe);

// Start observing the target node for configured mutations
observer.observe(targetNode, config);

// Trigger for static content
observe();
Agi Sferro
  • 626
  • 3
  • 12
  • Hi Agi, Thanks for testing. Yes, indeed, the code works only for preset images (in my case, about 3-4 images) however I wanted to catch all images. Any ideas how to observe changes to DOM ? I have tried a lot of tricks but failed. I even tried unregistering and registering my extension (after the page has loaded completely), but to no help :( – Greg Feb 14 '20 at 15:53
  • You can use `MutationObserver`, see my updated answer (can you also accept it if it works for you, thanks :)) – Agi Sferro Feb 21 '20 at 17:09