0

I decided to venture a bit into creating a chrome extension, and decided to implement a simple extension which prevents me from visiting facebook / linkedin more than 5 times a day.

However, i keep getting a number of errors, which I cant seem to debug. They are:

enter image description here

It's strange how it says cannot read undefined when it seems to be defined in the chrome API.

Here are the files I used:

manifest.json

{
  "manifest_version": 2,
  "name": "Distract Me Not",
  "version": "0.1",
  "permissions": ["webNavigation"],
  "content_scripts": [
  {
    "matches": [
     "https://*.facebook.com/","https://*.linkedin.com/"
    ],
    "js": ["content.js","jquery3.1.1.js","background.js"]
  }
]
}

content.js

chrome.webNavigation.onCompleted.addListener(function(details) {
    chrome.tabs.executeScript(details.tabId, {
        file: 'background.js'
    });
});

background.js

function getDate(){
    var today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth()+1; //January is 0!
    var yyyy = today.getFullYear();

    if(dd<10) {
        dd='0'+dd
    } 

    if(mm<10) {
        mm='0'+mm
    } 

    today = dd+'/'+mm+'/'+yyyy;
    return(today);
}

function main() {
    appName = $.getJSON("settings.json" , function(json){
        return json["appName"];
    });

    websiteLimits = $.getJSON("settings.json" , function(json){
        return json["websiteLimits"];
    });

    currentPage = window.location.hostname;
    currentWebsiteLimit = websiteLimits[currentPage];

    checkFor = appName + getDate();
    item = localStorage.getItem(checkFor);
    if (item) {
        item = Number(item);
        if (item > currentWebsiteLimit) {
            document.write("Sorry! Your limit for " + currentPage + " has been reached for today.");
            return;
        }
        localStorage.setItem(checkFor,item+1);
        return;
    }
    localStorage.setItem(checkFor,1);
}

main();

settings.json

{"appName":"distract me not",
"websiteLimits":{"facebook.com":5,
                "linkedin.com":5}
}

It seems fairly straightforward, yet it alludes me. I'm probably missing something simple, and would love some guidance on how to solve this!

Thank you! :)

UPDATE:

I realized the files should be in the other order, and that i didnt clear the previous errors so I was misled that the same errors were happening.

However,the script doesn't seem to be counting properly (the alert line in content.js alerts twice for one reload). Is there a way around this? Also, I see $.getJSON does not work to get local files. Is there a way i can abstract out settings to another json and load it, or is this the only way?

thanks alot! :)

manifest.json

{
  "manifest_version": 2,
  "name": "Distract Me Not",
  "version": "0.1",
  "permissions": ["webNavigation","tabs","https://*.facebook.com/","https://*.linkedin.com/"],
  "background":{
    "scripts":["background.js"]
  },
  "content_scripts": [
  {
    "matches": [
     "https://*.facebook.com/","https://*.linkedin.com/"
    ],
    "js": ["jquery3.1.1.js","content.js"]
  }
]
}

content.js

function getDate(){
    var today = new Date();
    var dd = today.getDate();
    var mm = today.getMonth()+1; //January is 0!
    var yyyy = today.getFullYear();

    if(dd<10) {
        dd='0'+dd
    } 

    if(mm<10) {
        mm='0'+mm
    } 

    today = dd+'/'+mm+'/'+yyyy;
    return(today);
}

function main(){
    var settings = {"appName":"distract me not",
                    "websiteLimits":{"www.facebook.com":5,
                                    "www.linkedin.com":5}
                    };

    appName = settings["appName"];
    websiteLimits = settings["websiteLimits"];
    currentPage = window.location.hostname;
    currentWebsiteLimit = websiteLimits[currentPage];

    alert(currentPage);

    checkFor = appName + getDate();
    item = localStorage.getItem(checkFor);
    if (item) {
        item = Number(item);
        if (item > currentWebsiteLimit) {
            document.write("Sorry! Your limit for " + currentPage + " has been reached for today.");
            return;
        }
        localStorage.setItem(checkFor,item+1);
        return;
    }
    localStorage.setItem(checkFor,1);
}

main();

background.js

chrome.webNavigation.onCompleted.addListener(function(details) {
    chrome.tabs.executeScript(details.tabId, {
        file: 'content.js'
    });
});
Wboy
  • 2,452
  • 2
  • 24
  • 45
  • 1
    See the [extension overview, architecture](https://developer.chrome.com/extensions/overview#arch): content script is different from a background page. See also [content script docs](https://developer.chrome.com/extensions/content_scripts) for a list of allowed API in a content script. – wOxxOm Oct 01 '16 at 11:47
  • Thanks for your reply, I dont understand why it needs to be rewritten though. i was following this http://stackoverflow.com/questions/9862182/on-page-load-event-in-chrome-extensions – Wboy Oct 01 '16 at 12:03
  • I did read it, I've set background.js to listen for the event (changed content.js to background.js) and likewise, changed manifest.json to have background script as background.js and content scripts as content.js. Still get the error.. How is the right way to do this? – Wboy Oct 01 '16 at 12:19
  • Apologies, I've updated the question :) Didn't know the errors do not auto clear, it's sort of working now, with other problems which I've mentioned in my question :) – Wboy Oct 01 '16 at 12:38
  • Right now your question is a huge monstrosity with half of it outdated. The existing answer seems to address your updated question - please clean your question to only include the updated version. – Xan Oct 03 '16 at 09:11

1 Answers1

2

You script running twice per page reload because of you include it twice per page reload.

Just see your code and understand it

manifest.json

...
"content_scripts": [
{
  "matches": [
     "https://*.facebook.com/","https://*.linkedin.com/"
  ],
  "js": ["jquery3.1.1.js","content.js"]
}
...

This code means: "please include my content.js and jquery3.1.1.js script to any page, which url matched to https://*.facebook.com/ or https://*.linkedin.com/ on DOM Ready".

background.js

...
chrome.webNavigation.onCompleted.addListener(function(details) {
  chrome.tabs.executeScript(details.tabId, {
      file: 'content.js'
  });
});
...

This code means: "please run content.js every time webNavigation.onCompleted triggered".

As you can see - both conditions are true on loading your LinkedIn ,so on script content.js runs twice and you see 2 alerts.

P.S> Is it correct that you only want to limit access to LinkedIn main page, not it's subpages ?

MobDev
  • 1,614
  • 17
  • 17
  • That is correct - hits on the main page only. And thank you for your reply, I understand this better now :) So if i understand correctly, the solution is to have content.js basically empty? – Wboy Oct 03 '16 at 15:04
  • Yes, you may clean content_script section in your manifest or background by your choice. I think if you are sure, that you are only wanna lock LinkedIn and Facebook sites - the better way is to save content_script, but remove background page. If you want to add another locks - it's better way to clean content_script section in manifest and make this logic on background page. – MobDev Oct 03 '16 at 21:16
  • And about your question about loading JSON config - you can use `` field to select file on your file system and `HTML5 FileReader API` for getting contents of file and parse it as JSON with `JSON.parse(...)`. But make sure, thet you are not using `` in popup.html - you can't process File Choose callback in that case - you may use inject script or popup window instead. Good docs about HTML5 FileReader is here: https://www.html5rocks.com/en/tutorials/file/dndfiles/ I may write tutorial if it is needed, but it's really easy. – MobDev Oct 03 '16 at 21:22