Javascript - code injected multiple times on specific website - javascript

I would like to know why and how to fix:
My code is being injected a few times while being o specific website, can't find why.
It should be injected only when visiting a specific url (it can be different for example tickets/*****).
manifest.json
{
"manifest_version": 2,
"name": "ext",
"version": "1.619",
"description": "Does things:)",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["https://www.example.com/agent/tickets/*"],
"js": ["foreground.js"]
}
],
"permissions": [
"tabs",
"activeTab",
"http://*/",
"https://*/"
]
}
background.js
chrome.tabs.onUpdated.addListener(function(id, info, tab){
/*if (tab.status !== "complete"){
return;
}*/
if(tab.url.indexOf("tickets") != -1){
console.log("injected");
chrome.tabs.executeScript(tab.id, {"file": "foreground.js"});
}
});

Related

JS - Chrome Extension - addEventListener('copy') not working

I am trying to develop a chrome extension however while trying to add an EventListener on the copy action it does not work (though supported by the browser because it is working on fiddle).
here are my different files.
manifest.json
{
"manifest_version": 2,
"name": "Bla",
"description": "bla",
"version": "1.0",
"browser_action": {
"default_icon": "camera.png",
"default_title": "bla"
},
"background": {
"page": "background.html"
},
"content_scripts" : [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["oncopy.js"]
}
],
"permissions": [
"activeTab",
"https://ajax.googleapis.com/",
"clipboardRead",
"clipboardWrite"
]
}
oncopy.js
document.addEventListener("copy", function() {
alert('copied')
}, true);
The alert never pops up.
I also tried with a similar code inside a background.js file called by background.html but didn't work either... Any ideas ?
Try this
document.addEventListener('readystatechange', function(evt) {
if (evt.target.readyState === "complete") {
document.addEventListener("copy", function() {
alert('copied')
}, true);
}
}, false);

How my chrome extension can be run automatically?

In this extension, if I click on the extension button and if current URL matches http://example.com/* or https://example.com/* it should be redirected to a new domain like http://NewDomain/* or https://NewDomain/*.
But I want this extension scan tab URL and perform redirection automatically in the following conditions:
if a new tab created or
if current tab URL changes
This is my code:
manifest.json
{
"manifest_version": 2,
"name": "My Extension",
"description": "Redirect example.com to NewDomain",
"version": "0.1",
"permissions":
[
"activeTab",
"tabs",
"background"
],
"browser_action":
{
"default_icon": "icon.png"
},
"content_scripts":
[
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content.js"]
}
]
}
scripts.js
var current_url = tab.url.split('/');
if(current_url[2] == "example.com")
{
current_url[2] = "NewDomain";
}
var new_url = current_url.join('/');
console.log('New tab url: ' + new_url);
document.location.href = new_url;
But it's not working, What changes should I apply?
Use a content script instead and drop the browser_action.
Then you can use document.location.href = "urlToRedirectTo";
The url matching can be done in the manifest
You have two options. Either specify the url to match in the manifest or match every url and check the url in the content script.
For example, this manifest will match all urls:
{
"manifest_version": 2,
"name": "whatever",
"description": "blah",
"version": "1.0",
"content_scripts": [
{
"matches": ["http://*/*", "https://*/*"],
"js": ["content.js"]
}
],
"permissions": [
"activeTab"
]
}
And in the content.js, you could do something like this:
if (document.location.href == "theUrlImLookingFor")
document.location.href = "theUrlThatIRedirectTo";

Trying to make an extension

I have an extension that i'm trying to add content scrips alongside background scripts but it just says invalid when trying to temp load.
{
"description": "Creates tasks and calculates application incomplete date",
"manifest_version": 2,
"name": "Task Creator",
"version": "1.31",
"permissions": [
"http://*/*", "tabs", "https://*/*",
],
"icons": {
"48": "icons/page-48.png"
},
"web_accessible_resources": [
"style/popUpStyle.css",
"script/popUpTask.js",
"script/logicTaskFiller.js",
"js/autosize.js",
"style/jquery-ui.css",
"js/jquery-1.12.4.js",
"js/jquery-ui.js"
],
"content_scripts":{
"matches": ["*urlhere.com*"],
"js": ["comSendForm.js"]
},
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icons/page-32.png"
}
}
I'm not quite sure where i'm messing up. It works instantly after I take out the content scripts, but I'm doing multiple things with this extension and I really do need the content scripts to run on a certain page. Any help is appreciated.
error message
1477430058898 addons.webextension. ERROR Loading extension 'null': Reading manifest: Error processing content_scripts: Expected array instead of {"matches":["*://url.com/"],"js":["comSendForm.js"]}
The error that you are getting is that your manifest.json has the value of the content_scripts key as an Object. The value of the content_scripts key needs to be an Array of Objects, not just an Object.
In addition, you have the following problems:
The line:
"http://*/*", "tabs", "https://*/*",
should not have the trailing ,. This is actually reported as the first error, so you may have copied the contents of your manifest.json file inaccurately.
Your matches pattern is invalid. You probably wanted something like:
"matches": ["*://*.urlhere.com/"],
With all of those changes your manifest.json would look like:
{
"description": "Creates tasks and calculates application incomplete date",
"manifest_version": 2,
"name": "Task Creator",
"version": "1.31",
"permissions": [
"http://*/*", "tabs", "https://*/*"
],
"icons": {
"48": "icons/page-48.png"
},
"web_accessible_resources": [
"style/popUpStyle.css",
"script/popUpTask.js",
"script/logicTaskFiller.js",
"js/autosize.js",
"style/jquery-ui.css",
"js/jquery-1.12.4.js",
"js/jquery-ui.js"
],
"content_scripts": [
{
"matches": ["*://*.urlhere.com/"],
"js": ["comSendForm.js"]
}
],
"background": {
"scripts": ["background.js"]
},
"browser_action": {
"default_icon": "icons/page-32.png"
}
}

chrome extension: run script after page has finished loading javascript

this is not firing at all when the page finishes loading. Basically when I click the browser action button, it will trigger it on, and on page load, it will run a script. In my background.js
var toggle = false;
chrome.browserAction.onClicked.addListener(function(tab) {
toggle = !toggle;
if(toggle){
chrome.browserAction.setIcon({path: "icons/logo.png", tabId:tab.id});
// chrome.tabs.executeScript(tab.id, {file:"SCRIPT.user.js"});
chrome.tabs.executeScript(tab.id, {code:"alert('aaxxxbbaa')"});
}
else{
chrome.browserAction.setIcon({path: "icons/icon48.png", tabId:tab.id});
chrome.tabs.executeScript(tab.id, {code:"alert('bbdxdb')"});
}
});
var filter = {'url': [
{hostSuffix: '*', pathPrefix: ''},
{hostSuffix: '*', pathPrefix: ''}
]};
chrome.webNavigation.onDOMContentLoaded.addListener(function(tab){
if (toggle)
chrome.tabs.executeScript(tab.id,{code:"alert('loaded')"});
},filter);
I've also tried to set it in the manifest
{
"name": "Tool",
"version": "0.0.1",
"manifest_version": 2,
"description": "Te",
"homepage_url": "",
"icons": {
"16": "icons/logo.png",
"48": "icons/logo.png",
"128": "icons/logo.png"
},
"default_locale": "en",
"background": {
"page": "src/bg/background.html",
"persistent": true
},
"browser_action": {
"default_icon": "icons/logo.png",
"default_title": "browser action demo"
},
"permissions": [
"<all_urls>"
],
"content_scripts": [
{
"run_at": "document_end",
"matches": [
"https://www.google.ca/*"
],
"css": [
"src/inject/inject.css"
]
},
{
"run_at": "document_end",
"matches": [
"https://www.google.ca/*"
],
"js": [
"src/inject/inject.js"
]
}
]
}
and in my inject.js
chrome.extension.sendMessage({}, function(response) {
var readyStateCheckInterval = setInterval(function() {
if (document.readyState === "complete") {
clearInterval(readyStateCheckInterval);
// ----------------------------------------------------------
// This part of the script triggers when page is done loading
console.log("Hello. This message was sent from scripts/inject.js");
// ----------------------------------------------------------
}
}, 10);
});
window.addEventListener ("load", myMain, false);
function myMain (evt) {
console.log('aaann');
var jsInitChecktimer = setInterval (checkForJS_Finish, 111);
function checkForJS_Finish () {
if ( typeof SOME_GLOBAL_VAR != "undefined"
|| document.querySelector ("SOME_INDICATOR_NODE_css_SELECTOR")
) {
clearInterval (jsInitChecktimer);
// DO YOUR STUFF HERE.
console.log('hi');
}
}
}
In your manifest file, you have duplicate content scripts, one with CSS and one with JS. It should look like this:
"content_scripts": [
{
"run_at": "document_end",
"matches": [
"https://www.google.ca/*"
],
"js": [
"src/inject/inject.js"
],
"css": [
"src/inject/inject.css"
]
}
]
Also, if you want it to match other urls, you will need to add them specifically, or use
"matches": ["<all_urls>"]
As for your proposed background script, that is essentially re-inventing the concept of content scripts, and it may not be in your best interest. I suggest sticking with the content script route.

How can I call functions defined in a Chrome Extension from regular websites?

I'd like to make a website that is not part of the chrome plugin but rather just uses some API that the plugin exposes to it. Is this possible and if so, how do I do it? I googled this question and was unable to find anything.
I'm trying to use content scripts but nothing happens. Can someone explain what's wrong here?
manifest.json
{
"manifest_version": 2,
"name": "Hello World Extension",
"description": "This extension prints hello world.",
"version": "1.0",
"background": {
"page": "background.html"
},
"browser_action": {
"default_icon": "img/icon.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://locahost:8888/*"],
"js": ["EmotivAPI.js"]
}
]
}
EmotivAPI.js
var port = chrome.runtime.connect();
console.log("Hello?");
window.addEventListener("message", function (event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
alert("recieved!");
}
}, false);
js in the webpage
window.sayHello = function () {
window.postMessage({ type: "FROM_PAGE", text: "Hello from webpage!" }, "*");
}
console.log('Emotiv extension loaded.');
}
I'm calling window.sayHello() from the console
Content Scripts can help you in this case.
The content script will be injected into a page:
"content_scripts": [
{
"matches": ["http://www.google.com/*"], // try with "http://localhost:*/*" or "http://localhost:*"
"css": ["mystyles.css"],
"js": ["content_script.js"]
}
]
If you want to inject the code only sometimes, use the permissions field instead
/* in manifest.json */
"permissions": [
"tabs", "http://*/*"
],
In you extension html file, you can then execute the script by:
chrome.tabs.executeScript(null, {file: "content_script.js"});

Categories