1

I'm trying to make an extension that collecting social networks links from the web page where user is. So when user clicking button getLinks we get all links and then by checking condition passing them in the blocks of the extension. I tried to use chrome.tabs.executeScript, and get links through urls = $$('a'); but it's not working

 $('#getLinks').click(function(e)
{
    var allLinks = [];
    var i = 0;
    chrome.tabs.executeScript( null, {"code": "urls = $$('a'); for (url in urls)
    { allLinks[i]=urls[url].href; i++;}"}, function() {
        var vk;
        var facebook;
        var linkedin;
        for (var i=0; i<allLinks.length; i++) 
        {
            var profil = (allLinks[i].href);
            if(profil.indexOf('vk.com')!=-1)
            {
                vk = profil;
                $('#vk').text(vk);
            }
            if(profilito.indexOf('facebook.com')!=-1)
            {
                facebook = profil;
                $('#fb').text(facebook);
            }
            if(profilito.indexOf('linkedin.com')!=-1)
            {
                linkedin = profil;
                $('#linkin').text(linkedin);
            }
        }
    });
});
Nikita Lvov
  • 97
  • 2
  • 14

2 Answers2

1

That's not how executeScript is used. That code can not access the variables allLinks and i because it is executed elsewhere. But you can make use of the returned value of that code like in this other SO question:

$('#getLinks').click(function(e) {
    chrome.tabs.executeScript( null, {"code": "var urls = document.querySelectorAll('a'); for(var i = 0; i < urls.length; i++) { urls[i] = urls[i].href; }; urls"}, function(results) {
        var allLinks = results[0];

        // use allLinks here
    });
});
ibrahim mahrir
  • 31,174
  • 5
  • 48
  • 73
  • I'm getting null in results and in allLinks variable – Nikita Lvov Jul 02 '18 at 01:02
  • I tried just to declare var x = 10; x in executeScript and it worked and transferred the value of 10 to results. But here it with urls it only gives me **null** value – Nikita Lvov Jul 02 '18 at 01:21
  • @NikitaLvov Maybe the `$$` is causing that. AFAIK it is only available in dev tools. Try an alternative like `querySelectorAll`. Check my edit! – ibrahim mahrir Jul 02 '18 at 01:26
  • I tried yours with `querySelectorAll` and I tried to use `document.links` but it gives me now just empty object – Nikita Lvov Jul 02 '18 at 01:42
  • @NikitaLvov Try injecting the code after document end using the [**`runAt`**](https://developer.chrome.com/extensions/tabs#method-executeScript) attribute. – ibrahim mahrir Jul 02 '18 at 01:49
  • Not working, IDK what else to try here. I'm even running it under `$(document).ready(function()` . The `document.links` as I said giving me empty object but the strange thing that `document.charset` for example works flawlessly. I suppose maybe it have limit to size? – Nikita Lvov Jul 02 '18 at 02:05
  • There are many things that can go wrong and without an [MCVE](/help/mcve) it's hard to guess. – wOxxOm Jul 02 '18 at 05:12
  • @NikitaLvov Try alerting or console logging the urls inside the injected code: `"...; alert(JSON.stringify(urls, null, 4)); urls"`. What are you getting? – ibrahim mahrir Jul 02 '18 at 13:01
  • if `{code: "var urls = document.querySelectorAll('a'); alert(JSON.stringify(urls, null, 4)); urls", runAt: "document_end"}` then I get empty object **{}** otherwise if `{code: "alert(JSON.stringify(urls, null, 4)); urls", runAt: "document_end"}` then I get **null** – Nikita Lvov Jul 02 '18 at 18:41
  • @NikitaLvov Well... Maybe you're injecting the code into the wrong place. Try: `code: "alert(document.title);"` or `code: "alert(location.href);"` to see if the code is injected into the right document. – ibrahim mahrir Jul 02 '18 at 23:04
  • Location is fine, it's executed on the site and injected on it. I found the solution actually here on [Stackoverflow](https://stackoverflow.com/questions/48333782/chrome-tabs-executescript-is-not-returning-results-from-content-page) After 2 days of googling I found that **DOM nodes** cannot be returned as result using `executeScript` – Nikita Lvov Jul 03 '18 at 01:19
  • Now I'm getting to another obstacle. When I'm trying to handle that array that full of objects collected from tags it turning it into undefined array with length of 1 – Nikita Lvov Jul 03 '18 at 01:34
  • @NikitaLvov Can you post the new code, the one that kind of works? – ibrahim mahrir Jul 03 '18 at 17:04
  • `chrome.tabs.executeScript(null,{code: 'Array.from(document.getElementsByTagName("a")).map(a => a.innerHTML)'},function (results){ console.log(results[0]); }); });` – Nikita Lvov Jul 03 '18 at 20:12
  • `chrome.tabs.executeScript(null,{code: 'Array.from(document.links).map(links => links.innerHTML)'},function (results){ console.log(results[0]); }); });` this work a bit better – Nikita Lvov Jul 06 '18 at 13:23
1

So finally I got an answer on my own question and posting here the solution

$('#getUser').click(function(e) {
chrome.tabs.executeScript(null,{code: 'Array.from(document.getElementsByTagName("a")).map(a => a.innerHTML)'},function (results){
    var vk = [];
    var facebook = [];
    var linkedin = [];
    var allElements = results[0];
    for (var i=0; i<allElements.length; i++) 
    {
    if (allElements[i].indexOf("https://vk.com") !== -1) 
    {
        vk.push (allElements[i]);
    }
    if (allElements[i].indexOf("https://facebook.com") !== -1 ) 
    {
        facebook.push (allElements[i]);
    }
    if (allElements[i].indexOf("https://www.linkedin.com") !== -1 ) 
    {
        linkedin.push (allElements[i]);
    }
    }
});

All links that we are finding on the page sorted in 3 arrays by belonging to the social networks

Nikita Lvov
  • 97
  • 2
  • 14