I'm having issues utilizing the materialize library within my chrome extension to display a custom modal when a button is clicked. I've already written code (in my content script) to inject a button to the existing web page. In my dialog.html, I have the HTML for my modal (using this template from materialize-css). Now, I'm trying to call $('.modal').modal('open'); inside a function that is called when the button is clicked (I've verified that the onclick is working fine, since console.log() works inside of this function.
However, when I try to run $('.modal').modal('open');, I get this error: Uncaught TypeError: $(...).modal is not a function. (I've also tried running $('.modal').modal(); and the other implementations I found on stackoverflow, but to no avail.
My manifest.json looks like:
{
"manifest_version": 2,
"name": "MyChromeExtension",
"version": "0.1",
"content_scripts": [
{
"matches": ["*://www.messenger.com/*"],
"css": ["/thirdParty/materialize.css"],
"js": ["/thirdParty/jquery.min.js","/thirdParty/materialize.js", "content-final.js"]
}
],
"web_accessible_resources": ["/thirdParty/bootstrap.min.css", "/thirdParty/jquery.min.js", "/thirdParty/bootstrap.min.js", "dialog.html", "/thirdParty/materialize.css", "/thirdParty/materialize.js"],
"permissions": ["tabs", "<all_urls>"],
"background": {
"scripts":["background.js"]
},
"content_security_policy": "script-src 'self' 'unsafe-eval' https://cdn.jsdelivr.net; object-src 'self'"
}
I've saved local copies of my jquery, bootstrap, and materialize files inside my folder thirdParty, but for some reason my code doesn't work. I've also tried installing all of these frameworks via npm and using browserify to combine them into my content-final.js, but this doesn't work either.
Does anyone know why this might be happening?
Related
I have a Chrome extension, that has different scripts for several pages:
{
"name": "My extension",
"version": "1.0.0",
"manifest_version": 3,
"content_scripts": [{
"matches": ["https://first/page"],
"run_at": "document_idle",
"js": ["first.js"]
}, {
"matches": ["https://second/page"],
"run_at": "document_idle",
"js": ["second.js"]
}]
}
I want to use some helper functions in both scripts. How do I load a second file, e.g. lib.js so that functions defined in there are available?
I've tried using chrome.runtime.getURL which gets me a URL to the file, but doesn't allow me to "load" it. I also tried just adding the file to the js property, which makes the file load but when trying to call the functions they are undefined. And I've tried several types of import statement, but haven't gotten them to work either.
So, how can I do this without duplicating the common code into both content script files?
A bit of a novice attempting to create my first Chrome extension here.
I've verified my JQuery and html code to be working by running it via opening it in a browser in a normal .html file that calls the .JS file.
However, the Chrome extension with the same code fails to run, seemingly due to CSP issues. (I am calling the ajax library in my html via https)
Refused to load the script
'http://www.reddit.com/r/abandonedporn/.json?jsonp=jQuery111307901595502626151_1438751974832&_=1438751974833'
because it violates the following Content Security Policy directive:
"script-src'self' https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js". send # library.js:5
I've modified my manifest.json file with every last thing that I thought necessary, including:
{"content_security_policy": "script-src 'self' https://ajax.googleapis.com/*; object-src 'self'"},
"permissions": [
"http://www.reddit.com/r/abandonedporn/.json?jsonp=?",
"http://www.reddit.com/*", "https://www.reddit.com/*",
"http://www.reddit.com/r/abandonedporn/",
"https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js/",
"http://www.reddit.com/r/abandonedporn/.json?jsonp=jQuery111309090442832093686_1438671168851&_=1438671168852",
"http://*/*", "https://*/*",
"http://reddit.com/json*",
"http://www.reddit.com/r/abandonedporn/*"],
and
"content_scripts": [
{
"matches": [
"https://www.google.com/*",
"http://www.reddit.com/abandonedporn/*"
],
"js": [
"src/inject/inject.js",
"src/content.js",
"src/override/get_pics.js",
"src/override/get_pics2.js",
"src/override/library.js"
]
}
]
}
Lastly, my actual Jquery script:
(Note that changing ".getJSON" to ".getScript" did not help.)
document.addEventListener('DOMContentLoaded', function () {
$.getJSON("http://www.reddit.com/r/abandonedporn/.json?jsonp=?", function(data) {
$.each(data.data.children, function(i,item){
$("<img/>").attr("src", item.data.url).appendTo("#images");
});
});
});
You can't load external (CDN) script files in chrome extension as per new CSP from google. You need to package all your resources, download jquery and access from your package. "jquery.min.js" instead CDN-URL/jquery.min.js. Here is in detail
So I've been trying to send data from a web page to the Chrome Application (not Chrome Extension). Reading stuff around, according to me, this primarily would require the use of url_handlers for invoking Chrome App from a web page, content scripts to inject JS into the web page and/or Messaging for communication between Chrome Application and the web page.
Also, installed App from it's .crx, else loading unpacked directory leads to this error:
"content_scripts is only allowed for extensions and legacy packaged apps, but this is a packaged app."
Now, I tried injecting JS in the required site. However, on inspecting using Chrome Dev Tools, there's no such entry in the Sources->Content scripts section for that site. It simply didn't inject itself when using a Chrome App. It works perfectly with extensions but I want to use Chrome App for other functionalities.
As an alternative, I looked for Messaging examples where its usage is mentioned as:
"... your app or extension can receive and respond to messages from regular web pages."
But, somehow I couldn't get it working.
Any headers on either of the approaches? Other Suggestions?
manifest.json:
{
"name": "App",
"version": "1.0",
"manifest_version": 2,
"minimum_chrome_version": "31",
"app": {
"background": {
"scripts": ["background.js"]
}
},
"permissions": [
{"fileSystem": ["write", "retainEntries", "directory"]},
"storage",
"http://example.com/*"
],
"externally_connectable": {
"matches": ["http://example.com/*"]
},
"content_scripts": [{
"matches": ["http://example.com/*"],
"js": ["content.js"]
}]
}
Indeed, you can't have content scripts in an app.
However, using externally_connectable is valid.
You have already declared that you want to be externally connectable from example.com. (Note: be careful when defining match patterns, for instance this one does not cover www.example.com)
In example.com's own scripts, you can then include the following:
chrome.runtime.sendMessage("idOfYourAppHere", message, function(response) {
/* ... */
});
And in the app (probably its background script) you can catch that with
chrome.runtime.onMessageExternal.addListener(function(message, sender, sendResponse) {
/* ... */
sendResponse(response);
});
This does require you to know the ID in advance. You can pin it by packing your extension and extracting the "key" field from the manifest. See this question for some more details.
I just started playing with Chrome extensions, trying to load JQuery from manifest file, and test if it's loaded. It is not loading, although I did specify it in content-scripts! Any idea why?
sample.js
if (typeof jQuery != 'undefined') {
alert("jQuery library is loaded!");
}
manifest.json
{
"manifest_version": 2,
"name": "__MSG_extName__",
"version": "0.1",
"default_locale": "en",
"background": { "scripts": ["sample.js"] },
"permissions": ["contextMenus"],
"minimum_chrome_version": "33",
"content_scripts": [{
"matches": ["<all_urls>"],
"css": ["style.css"],
"js": ["lib/jquery-1.11.0.js"]
}]
}
As noted in the comments to the question, you are doing things in two different contexts.
The "background" key defines what is loaded in a single invisible page where the "main" code resides.
"content_scripts" injects code into other pages instead, that can communicate with the background page via Chrome API.
A good overview is available here.
It's not immediately clear why <all_urls> match pattern does not inject the script into your background page, but fact is, it's not.
How to modify your example depends on what you try to achieve.
If you need sample.js to be executed on every page when it loads, you need to move it to the "content_scripts" key. Note that most of the Chrome API will be unavailable.
If you also need jQuery in your background page (doubtful, but possible), you can add it to the background.scripts list.
If you need some processing done that is not available to the content scripts, then you need to have two scripts, one background script that does the work and an injected content script that communicates with it via Messaging API.
To inject jQuery to every page you can do use this approach.
Add the following line to the manifest.json file. This specify that packaged resource (jQuery file inside extension) is expected to be usable in the context of a web page.
"web_accessible_resources": ["lib/jquery-1.11.0.js"]
Add the following code into new file located in your (file manifest.json) "content_scripts: [{ "js": new_file.js }]" to actually inject jQuery when onLoad event triggers:
The new_file.js file:
var s = document.createElement('script');
s.src = chrome.extension.getURL('lib/jquery-1.11.0.js');
(document.head||document.documentElement).appendChild(s);
s.onload = function() {
s.parentNode.removeChild(s);
};
Okay, so here's my problem:
On my home computer, I have a Google Chrome Extension installed - WXFZ's \Code. This extension works perfectly, I use it every day for work purposes. However, I guess the developer gave up on it, because it can no longer be found on the Google Extensions download page.
I'm trying to transfer that extension from my home computer to my office computer. I have the extension folder on my work computer and I've tried dragging and dropping it into the extensions page to install it, but I receive an error:
"Could not load extension from 'U:\Downloads\pekinghlicdifnlgafajjohhoiochfdh\2.1_0'. The 'manifest_version' key must be present and set to 2 (without quotes). See developer.chrome.com/extensions/manifestVersion.html for details."
I'm not entirely sure what that means, but I've copied the contents of the manifest folder below. I've tried changing some things around in the manifest file, but nothing would work :/
{
"app": {
"launch": {
"local_path": "bscode.html"
}
},
"background_page": "storage.html",
"content_scripts": [ {
"all_frames": true,
"js": [ "js/jquery-1.4.4.min.js", "js/bscode.js", "js/bscode-cs.js" ],
"matches": [ "http://*/*", "https://*/*" ]
} ],
"description": "Simple \\code and \\\\macro engine for common web-forms.",
"icons": {
"128": "icon_128.png",
"16": "icon.png",
"48": "icon_48.png"
},
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClVb9xGcyZp3P4Fe+rpjGUqVrvRq8rqQl278gMjFzmxqD65cu7uf/erOBlFWbAc6YK15yvgnsYn+HDYvoSV4shajLAnytek7CI35nia5AnYACJsXW+JrfoT9pEgK9Zd4fE1XFr8bNCzhwKeoupH+gtMdvJ9lqAN4Xj/Tam5+QvzQIDAQAB",
"name": "wxfz\u2019s \\code",
"permissions": [ "http://*/*", "https://*/*", "tabs" ],
"update_url": "http://clients2.google.com/service/update2/crx",
"version": 2
}
Any advice on this problem, I'd appreciate it. Like I said, the extension still works; I was assuming there has to be a way to get it to work on my other computer :/
UPDATE
My apologies, the updated source code is :
{
"app": {
"launch": {
"local_path": "bscode.html"
}
},
"background_page": "storage.html",
"content_scripts": [ {
"all_frames": true,
"js": [ "js/jquery-1.4.4.min.js", "js/bscode.js", "js/bscode-cs.js" ],
"matches": [ "http://*/*", "https://*/*" ]
} ],
"description": "Simple \\code and \\\\macro engine for common web-forms.",
"icons": {
"128": "icon_128.png",
"16": "icon.png",
"48": "icon_48.png"
},
"key":"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQClVb9xGcyZp3P4Fe+rpjGUqVrvRq8rqQl278gMjFzmxqD65cu7uf/erOBlFWbAc6YK15yvgnsYn+HDYvoSV4shajLAnytek7CI35nia5AnYACJsXW+JrfoT9pEgK9Zd4fE1XFr8bNCzhwKeoupH+gtMdvJ9lqAN4Xj/Tam5+QvzQIDAQAB",
"name": "wxfz\u2019s \\code",
"permissions": [ "http://*/*", "https://*/*", "tabs" ],
"update_url": "http://clients2.google.com/service/update2/crx",
"version": "2.1"
"manifest_version": 2
}
In the original post I had:
"version": 2
I see now that was incorrect, it was supposed to be 2.1, so I changed that back, along with making the changes you suggested.
The error you get is asking for a "manifest_version": 2 property in your manifest.json. So, at the very least youneed to:
Change "version": 2 to "version": "2" (version must be a string value).
Add "manifest_version": 2 (2 without quotes - it's a number value).
Change "background_page": "storage.html", to "background": {"page": "storage.html"},.
Beware though that some features may break and need refactoring as well (in order to conform with manifest v2).
UPDATE:
It turned out there were quite a few things that needed to be changed in order for the extension to be compliant with Manifest V2 (and functional). The re is no point in posting the code here or list every single modification in detail, so I'll try to summarize and focus on the "nature" of the modification (see further down for a link to the updated source code):
The major source of problems was the fact that the new Content Security Policy (CSP) that applies to Google Chrome Extensions does not allow eval and inline scripts/event listeners. To circumvent this the following changes were necessary:
Declare a CSP in the manifest that allows eval
("content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'").
Unfortunately(?) there is no way to relax the policy against inline scripts.
In the background page (namely storage.html, an inline script was used, so I ended up moving the code to an external file (background.js) and including the JS scripts like this:
"background": {
"persistent": true,
"scripts": [
"js/bscode.js",
"js/background.js"
]
},
The old jquery-1.4.4 (which relies on inline scripting) was a no go as well. So I had to replace to the less old jquery-1.7.2 (I tried using the latest versions of jquery and jquery-ui, but they didn't play well with the rest of the code, so I rolled back to the oldest version that didn't rely on inline scripting). This change affected both the content_scripts declaration and bscode.html (where the user-defined macros are defined and edited).
Migrating to jquery-1.7.2 required porting all occurrences of the deprecated .live() to the equivalent syntax using .on(). (Luckily, this only affected one file: chrome-ui.js)
bscode.html had 2 inline scripts that needed to be moved to an external file (and placed at the right place inside the body, since the code calls document.write.
bscode.html had a lot of inline event listeners, which would not work. Furthermore, elements (which also contain inline event listeners) are inserted dynamicaly into the DOM, so the solution had to take that into account as well.
I tackled both the problems by using an external JS file that utilizes a MutationObserver to listen for node insertions and convert any inline event listeners to "attached" event listeners (by means of addEventListener()).
Finally, to make things easier, I set-up bscode.html as the Options Page for the extension, so you can quickly bring it up from the chrome://exrensions page.
(I hope I didn't leave something out...)
The refactored (and fully functional as far as I can tell) source code of the extension can be downloaded here.