Chrome extension causes problems with jquery and javascript on some pages - google-chrome

I have a small chrome extension which I want to use to change text. It works just the way I want it to(clicking the icon changes text), but on some pages the existing jquery stops working when the app is enabled. What am I doing wrong?
Files: manifest.json, myscript.js and background.html
manifest.json content:
{
"name": "My extension",
"version": "1.0",
"background_page": "background.html",
"permissions": [
"tabs", "http://*/*"
],
"content_scripts": [
{
"matches": ["http://*/*"],
"matches": ["https://*/*"],
"js": ["myscript.js"]
}
],
"browser_action": {
"default_icon": "icon.png"
}
}
myscript.js content:
var array = {"not":" NOT ", "like":" LIKE ", "job":"JOBS"}
for (var val in array)
document.body.innerHTML = document.body.innerHTML.replace(new RegExp(val, "g"), array[val]);
background.html content:
<script>
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null,
{file:"myscript.js"});
});
</script>

document.body.innerHTML is very bad.
When you use it, you're treating DOM nodes as raw text. Those DOM nodes have event handlers and even a simple document.body.innerHTML+='...' will send the existing nodes to oblivion, creating new ones, without event handlers.
So instead, you need to iterate through all the text nodes in the document (*see here how) and do an innerHTML each one individually.
Sănătate!

Related

Chrome - Message passing - From popup click to context script on specific tab

Can you tell me why the following code is not working. Here is my code :
Popup.js (not a backgorund script) :
chrome.tabs.create({url: url}, function(tab) {
chrome.tabs.executeScript(tab.id, {file: 'connect.js', allFrames:true}, function() {
chrome.tabs.sendMessage(tab.id, 'whatever value; String, object, whatever');
});
});
content script :
chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
console.log(message);
// Handle message.
// In this example, message === 'whatever value; String, object, whatever'
});
And my manifest :
{
"name": "AN App",
"version": "1.0",
"description": "To connect",
"permissions": [
"storage",
"activeTab",
"tabs",
"https://*/*"],
"browser_action": {
"default_popup": "popup.html"
},
"content_scripts": [{
"matches": ["https://*/*"],
"js": ["connect.js"]
}],
/*
"background": {
"scripts": ["background.js"]
},*/
"manifest_version": 2
}
I don't understand, the console debug in the tab do not display anything...
I also try from the popup to the background and then from the background to the tab but nothing happen neither (I'm quite new at chrome extension so I hope u can help me)
Thanks,
Regards
Martin
I found the solution. When I call chrome.tabs.create from the JS inside the popup it closes the code running in the popup and the message is never sent.
So instead of calling the chrome.tabs.create inside the JS linked to the popup, I just send a message to the background script, the background script call chrome.tabs.create (like this it runs in background and the code do not stop from executing).
And then the message function works correctly like chrome doc says.
Martin

Chrome Extension - Append HTML & Run jQuery Function on Extension Click

So I'm in the midst of creating my first Chrome Extension (Trying)
I feel like I'm close... But I genuinely don't know what to google to get the answers I need. So I'm sorry if this is a silly question.
Essentially what I'm trying to do is on click of extension - Append HTML & CSS to body and run a jQuery function. But from the looks of it, I need to call in jQuery in the manifest? Which I think I've done and it's still not working.
My Code:
manifest.json
{
"name": "Title",
"description": "Description",
"version": "1.0",
"browser_action": {
"default_title": "Hover Title",
"default_icon": "icon.png"
},
"content_scripts": [ {
"js": [ "jquery-1.7.2.min.js", "background.js" ],
"matches": [ "http://*/*", "https://*/*"]
}],
"manifest_version": 2
}
background.js
chrome.browserAction.onClicked.addListener(function(tab) {
(function ($) {
$('body').append("Hello");
alert("Hello");
console.log("Hello");
}(jQuery));
});
Any insight into where I'm going wrong would be massively helpful!
Thank you!!
Chrome extension architecture is simple but it doesn't mean one can write code without studying it.
There are two methods of injecting content scripts:
Unconditionally on all specified urls, in which case "content_script" key is used in the manifest and the content scripts communicate with the background page via runtime.sendMessage.
Only when some event occurs like e.g. the user clicks our toolbar icon, in which case we only need the permission to access the active tab.
So in the given case we'll attach the icon click handler and inject the code afterwards:
manifest.json:
{
"name": "Title",
"description": "Description",
"version": "1.0",
"browser_action": {
"default_title": "Icon Title",
"default_icon": "icon.png"
},
"background": {
"scripts": ["background.js"]
},
"permissions": ["activeTab"],
"manifest_version": 2
}
background.js (this is an event page because we didn't use "persistent": true in the manifest, so be advised that the [global] variables will be lost after a few seconds of inactivity; instead you should use chrome.storage API or HTML5 localStorage/sessionStorage/and so on):
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript({file: "jquery-1.7.2.min.js"}, function(result) {
chrome.tabs.executeScript({file: "content.js"}, function(result) {
});
});
});
content.js (the code runs in a sandbox so there's no need to hide global variables using IIFE)
$('body').append("Hello");
alert("Hello");
console.log("Hello");

Can't get Chrome Context Menu item to show on Chrome Extension

I have a Chrome extension that opens a KML/KMZ file in Google Maps. The extension is triggered when the user right-clicks a link to the KML document. But the context menu does not appear. It uses a background script. Here is the manifest.json:
{
"manifest_version": 2,
"name": "KML/KMZ Viewer",
"version": "1.0.0",
"description": "Can be used to view KML/KMZ Files.",
"icons": {
"19": "tiny.jpg",
"24": "icon.png",
"128": "image.png"
},
"permissions": [
"tabs",
"contextMenus",
"activeTab",
"background"
],
"background": {
"scripts": ["background.js"]
}
}
Here is the background.js:
// Set up context menu at install time.
chrome.runtime.onInstalled.addListener(function() {
menuCreate();
console.log('Issued function');
});
// add click event
chrome.contextMenus.onClicked.addListener(onClickHandler);
// The onClicked callback function.
function onClickHandler(info, tab) {
var url = info.selectionText;
openWin(url);
};
function openWin(kml) {
chrome.windows.create({"url":"http://www.nearby.org.uk/google/fake-kmlgadget.html? up_kml_url="+kml+"&up_view_mode=earth&up_lat=&up_lng=&up_zoom=&up_earth_2d_fallback=1&up_earth_fly_from_space=1&up_earth_show_nav_controls=1&up_earth_show_buildings=1&up_earth_show_terrain=1&up_earth_show_roads=1&up_earth_show_borders=1&up_earth_sphere=earth&up_maps_streetview=1&up_maps_default_type=hybrid"});
}
function menuCreate() {
chrome.contextMenus.create({"title": "Open KML/KMZ", "contexts": ["link"], "id": "kmlopen", "targetUrlPatterns": ["*.kml", "*.kmz"]});
console.log('Function ran');
}
Yet when I right-click on a link to a KML or KMZ file, the context menu doesn't show. According to the JavaScript console, the functions ran. This is what the console outputs when I run chrome.contextMenus.create({"title": "Open KML/KMZ", "contexts": ["link"], "id": "kmlopen", "targetUrlPatterns": ["*.kml", "*.kmz"]}); manually under _generated_background_page.html I get the kmlopen, the id of the menu item. What am I doing wrong? The openWin(/*some url*/); function works fine.
Wrong pattern.
The patterns follow the standard Match pattern format.
So you should use the patterns
"targetUrlPatterns": ["*://*/*.kml", "*://*/*.kmz"]
However, be mindful of query strings.

Background page function not triggered in google chrome:

I am using the following code to access the background page function in google chrome
popup.html
function sendRequest(ea,eb)
{
console.log("Inside");
chrome.extension.sendRequest({ea:ea,eb:eb},
function(response)
{
alert(response.farewell);
});
}
background.html
<html>
<body>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
sendResponse({farewell: "goodbye"});
})
</html>
</body>
</script>
manifest.json
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"background": {
"page": "background.html"
},
"content_scripts": [
{
"matches": ["http://*/"],
"js": ["popup.js"]
}
],
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "mine.html"
},
"permissions": [
"tabs","http://*/","background"
],
"web_accessible_resources": ["loading.html","bu.png"]
}
However it does not print the alert. Can anyone tell me what i am doing wrong here?
Your HTML for background.html is extremely malformed and should be fixed;
<html>
<body>
<script>
chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) {
sendResponse({farewell: "goodbye"});
})
</script>
</body>
</html>
Tags should be closed in the reverse order of them being open to maintain a correct hierarchy. Since you had not done so, the <script> element was malformed and contained invalid syntax </html></body> so would not be executed correctly.
Since you're using version 2 of the manifest you may want to consider abstracting the contents of this script element (ignoring all HTML) to its own file (e.g. background.js) and change your manifest to the following;
{
"name": "My First Extension",
"version": "1.0",
"manifest_version": 2,
"minimum_chrome_version": "18",
"background": {
"scripts": ["background.js"]
},
"content_scripts": [
{
"matches": ["http://*/"],
"js": ["popup.js"]
}
],
"description": "The first extension that I made.",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "mine.html"
},
"permissions": [
"tabs","http://*/","background"
],
"web_accessible_resources": ["loading.html","bu.png"]
}
Notice that the background property now contains an array of strings representing JavaScript files to be loaded (in the order specified) in to a dynamically generated background page.
I've also set the minimum_chrome_version property to 18 as manifest version 2 should only be used when targeting this version of Chrome and above.
Developers should now only really need to use background pages instead of scripts when they need to support older versions of Chrome.
Edit
It just clicked that you're attempting to execute embedded JavaScript within your background page. Manifest version 2 introduces Content Security Policies which prohibit the execution of inline (e.g. onclick="showDialog();" and href="javascript:void(0);") and embedded JavaScript. This is why your background.html won't work and why background.js will. You will also want to ensure your popup.html doesn't contain any embedded JavaScript. The best workaround (and generally best practice anyway) is to abstract all JavaScript into its own file (e.g. popup.js) which is referenced by the HTML file. For example;
<script src="/popup.js"></script>

Chromium extension: javascript not executed

Making a simple plugin , which executes javascript when a page is loaded , and I want to execute different javascript on different page
But the following code wasn't working as expected , no "alert" was triggered:
background.html:
<html><body>
<script>
chrome.webRequest.onCompleted.addListener(
function(details) {
alert (details.url);
},
{
urls: ["*"],
types: ["main_frame"]
},
[]
);
</script>
</body></html>
manifest.json:
{
"name": "JS",
"background_page": "background.html",
"permissions": [
"webRequest",
"*"
],
"version":"0.10"
}
Alerts and console.log made from the background page of an extension simply aren't visible on the general pages.
If you want to see them, you have to open the background page : Go to the extensions settings page (menu tools/extensions) and click the "background.html" link below the name of your extension.
In your case it may be better, during development phase, to simply add the console.log and alerts in the content scripts (i.e. not the background page). So you can read them without opening the background page.
EDIT : as requested, an extension that will simply alert the location :
main.js :
alert(document.location.href);
manifest.json :
{
"name": "Any name",
"version": "3.3",
"background_page": "background.html",
"content_scripts": [
{
"matches": ["http://*/*"],
"all_frames" : true,
"run_at" : "document_end",
"js": [
"main.js"
]
}
]
}
Yes I tested it. And yes it's as painful as it sounds. You should use console.log instead of alert during your dev.