I'm working on building a Chrome extension for a forum, but the problem is the JavaScript for my popup.html won't do anything. I added alert("popup.js running...") at the top and it does come up but then my popup doesn't display at all. This is a problem because JavaScript is going to be required for the popup page. I'm kind of lost, so I'm assuming I'm just missing something that is preventing my JavaScript from running. I heard the AdBlock extension would prevent it from running but I removed that and it still didn't work. Anyone see a problem?
manifest.json
{
"name": "Riggy",
"short_name": "Riggy",
"description": "Create your own Roblox Forum signature with Riggy!",
"version": "0.0.1",
"manifest_version": 2,
"browser_action": {
"default_popup": "popup/popup.html"
},
"permissions": [
"storage"
],
"content_scripts": [
{
"matches": ["http://www.roblox.com/*"],
"js": ["scripts/jquery.js", "scripts/content.js"]
}
]
}
popup.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="popup.css" />
<script type="text/javascript" src="scripts/jquery.js"></script>
</head>
<body>
<span class="title">Riggy</span><br />
<span>Signature: </span><input name="siggy" id="siggy" value="Riggy is greatness!" />
<span id="output">[output]</span>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>
popup.js
alert("popup.js running");
$(document).on("ready", function() {
var siggy = $("#siggy");
var output = $("#output");
function message(text) {
output.html(text);
}
siggy.change(function() {
chrome.storage.sync.set({"siggy": siggy.val()}, function() {
message("Saved signature.");
});
});
message("Riggy is ready!");
});
I had the same exact problem with an extension of mine, I believe it was fixed after I added this to the manifest file.
manifest.json
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
More info here: http://developer.chrome.com/extensions/contentSecurityPolicy.html.
Related
I'm trying to create a chrome extension, so I'm doing tutorials to learn and reading a bunch, but I'm struggling. I'm doing this tutorial. But long-term, from the extension I need users to be able to login to their account, then as they're browsing, send the url that they're at to their account.
popup.html
<!doctype html>
<html>
<head>
<title>Add a Snippet</title>
<script src="popup.js"></script>
<link rel="stylesheet" type="text/css" href="popup.css">
</head>
<body>
<h1>Add a Snippet</h1>
<form id="form">
<textarea id="code"></textarea>
<button type="submit" id="checkPage">Add Snippet</button>
</form>
</body>
</html>
popup.js
What I REALLY don't understand is that according to the console.log lines that I have in there and the error, it's loading the DOMContent, and it doesn't have any problem with finding the form by the id (let f = document.getElementById('form');). But it bombs when I try to attach an event listener?
document.addEventListener('DOMContentLoaded', function() {
console.log('the domcontentloaded');
let f = document.getElementById('form');
f.addEventListener('submit', function(e){
console.log('the form was submitted');
e.preventDefault();
})
}, false);
manifest.json
{
"name": "My Awesome Plugin",
"description": "This extension will be awesome",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html",
"default_title": "This is Awesome"
},
"background": {
"scripts": ["jquery-2.2.3.min.js", "background.js","popup.js"],
"persistent": false
},
"permissions": [
"activeTab",
"declarativeContent",
"https://ajax.googleapis.com/",
"storage",
"tabs",
"http://*/*",
"https://*/*"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": ["login.js"]
}
],
"manifest_version": 2
}
login.js
console.log('login.js is ready to party');
When I load, I get this in the background inspector (or whatever it's called). So it's not finding the form.
So I looked at the elements, and I'm confused because it's not showing the form or the textarea. But when I click on the chrome extension icon, it's there.
1/Remove popup.js from "background/scripts" section of your manifest.
2/Add popup.js as a script reference in your popup.html file.
This way, popup.js will operate in the context of the popup.html DOM.
My extension is intended to inject some HTML elements using local JavaScript libraries such PrimeUI, jQueryUI and its correspondent CSS stylesheets.
The best way I have found to do so, is to inject the HTML as follows:
// test.js
$.get(chrome.extension.getURL('/overlay.html'), function(data) {
$($.parseHTML(data)).appendTo('body');
}
// manifest.json
{
"name": "Test",
"version": "1.0",
"manifest_version": 2,
"options_page": "",
"description": "Test",
"browser_action": {
"default_title": "Test",
"default_popup": ""
},
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"js/jquery-3.1.1.min.js",
"js/test.js"
]
}
],
"permissions": [
"tabs"
],
"web_accessible_resources": [
"overlay.html",
"css/font-awesome.min.css",
"css/jquery-ui.min.css",
"css/primeui-all.min.css",
"js/jquery-3.1.1.min.js",
"js/jquery-ui.min.js",
"js/primeelements.min.js",
"js/primeui-all.min.js",
"js/main.js"
]
}
I have the required JavaScript libraries inside "js" folder in the root directory, for security reasons I do not retrieve them from a CDN.
My HTML contains CSS and JS on <head> section, but the styles nor the scripts applies in any way.
<html>
<head>
<link rel="stylesheet" href="css/font-awesome.min.css"/>
<link rel="stylesheet" href="css/jquery-ui.min.css"/>
<link rel="stylesheet" href="css/primeui-all.min.css"/>
<script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui.min.js"></script>
<script type="text/javascript" src="js/primeui-all.min.js"></script>
<script type="text/javascript" src="js/x-tag-core.min.js"></script>
<script type="text/javascript" src="js/primeelements.min.js"></script>
</head>
<body>
<button id="btn-show" type="button">Show</button>
<div id="dlg" title="Godfather I">
<p>The story begins as Don Vito Corleone, ...</p>
</div>
</body>
</html>
// main.js
$(function() {
$('#dlg').puidialog({
showEffect: 'fade',
hideEffect: 'fade',
minimizable: true,
maximizable: true,
responsive: true,
minWidth: 200,
modal: true,
buttons: [{
text: 'Yes',
icon: 'fa-check',
click: function() {
$('#dlg').puidialog('hide');
}
},
{
text: 'No',
icon: 'fa-close',
click: function() {
$('#dlg').puidialog('hide');
}
}
]
});
$('#btn-show').puibutton({
icon: 'fa-external-link-square',
click: function() {
$('#dlg').puidialog('show');
}
});
}
The button is successfully displayed but with no events are attached nor styles.
i.e: if I inject this code on StackOverflow my button get the styles from SO and not mine.
I want to avoid as much as possible JavaScript for creating elements, or injecting tags programmatically, to separate the View from the Controller.
How can I manage to use my styles and scripts with my injected HTML as we do ordinarily? I have tried adding them to web_accessible_resources, and other manifest fields unsuccessfully.
Makyen explained:
It is not possible to parse HTML with <head> elements hardcoded such <script> and <link>. Instead it should be injected in other way.
The ways I have chosen to inject the files are:
For the CSS:
// Test.js
/** CSS Injection */
var link = document.createElement("link");
link.href = chrome.extension.getURL("css/jquery-ui.min.css");
link.type = "text/css";
link.rel = "stylesheet";
document.getElementsByTagName("head")[0].appendChild(link);
For the JS:
// Test.js
/** JavaScript Injection */
var s = document.createElement('script');
s.src = chrome.extension.getURL('js/jquery-3.1.1.min.js');
// "When an inline script is inserted in the document, it's immediately executed
// and the <script> tag can safely be removed". – Rob W.
s.onload = s.remove;
(document.head || document.documentElement).appendChild(s);
Trying to insert large amounts of code/libraries as into the page context using tags has a significant chance of interfering with the current contents/JavaScript of the page. Is there a reason that you are inserting scripts into the page context? Normally, you would have these inserted scripts (and CSS) as content scripts (manifest.json
content_scripts, or chrome.tabs.executeScript()/chrome.tabs.insertCSS(). not in the page context. – Makyen
With the above code I have successfully injected the files, but the styles and functions are applied only sometimes, I will edit when I fix this.
I am currently writing a chrome extension. This is the manifest:
{
"manifest_version": 2,
"name": "whatever",
"short_name": "whocares",
"description": "blabla",
"version": "1.0.2",
"author": "me",
"permissions": [
"http://ajax.googleapis.com/"
],
"content_scripts": [
{
"matches": ["https://plus.google.com/*"],
"js": ["jquery-1.10.2.min.js","filter.js","settings.js","settings.html"]
}
],
"options_page": "settings.html",
"browser_action": {
"default_icon": "nicepic.png"
}
}
This is the options.html page:
<html>
<head>
<script type="text/javascript" src="settings.js"></script>
</head>
<body onload="CollectSettings()">
<h2>Options:</h2>
<form>
(some stuff)
</form>
</body>
</html>
The following error is thrown:
Refused to execute inline event handler because it violates the
following Content Security Policy directive: "script-src 'self'
chrome-extension-resource:".
CollectSettings() is a function within the settings.js
I thought there are only JS-Limitations of that kind in background - Scripts, not on the options-Page?
The Chrome Extensions Content Security Policy (CSP), which among other things prevents the execution of inline JavaScript, applies to the background-page and all views of an extension (including any popup's).
In fact, the example used in the section Inline JavaScript will not be executed is a typical case where those restrictions are effective on a browser-action popup.
Thanks for taking the time to read this.
Here is the directory of my extension folder.
And here is the manifest code :
{
"manifest_version": 2,
"name": "Technobuffalo Stories",
"description": "Your Description about Extension goes here",
"version": "1.0",
"content_scripts": [ {
"js": [ "popup.js" ],
"matches": [ "http://feeds.feedburner.com/*" ]
} ],
"permissions": [ "http://feeds.feedburner.com/*" ],
"browser_action": {
"default_icon": "icon_16.jpeg",
"default_popup": "popup.html"
}
}
Here is popup.html :
<html>
<head>
<title>Technobuffalo Stories
</title>
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script src="popup.js"></script>
</head>
<body>
<div id="feed" style="background-color:orange;height:500px;width:500px;" ></div>
</body>
</html>
and last of all here is popup.js :
google.load("feeds", "1");
function initialize() {
var feed = new google.feeds.Feed("http://feeds.feedburner.com/technobuffalo/rss?format=xml");
feed.load(function(result) {
if (!result.error) {
var container = document.getElementById("feed");
for (var i = 0; i < result.feed.entries.length; i++) {
var entry = result.feed.entries[i];
var div = document.createElement("div");
div.appendChild(document.createTextNode(entry.title));
container.appendChild(div);
}
}
});
}
google.setOnLoadCallback(initialize);
When I open the popup.html file as it is, the required result is displayed but when I load the Chrome extension, only the background color of the div can be seen. Is there any problem with the permissions that I have set or is it something else?
Thanks,
Yash.
You have to add the following line to manifest.json to be able to use resources from www.google.com:
"content_security_policy": "script-src 'self' https://www.google.com; object-src 'self'"
As Rob W already pointed out this is a security feature that has been introduced with manifest version 2.
I wants to create an extension where content script will send message to background page and then on browser action means clicking on extension icon will access that background page and get some data.I am using chrome Version 23.0.1271.64 m on windows8.
I am getting following error.
Port error: Could not establish connection. Receiving end does not exist.
I tried to solve the same. but people are using sendRequest which is not supported by chrome20+. i also found solution mentioned for chrome 20+. But not working. Please help.
Below is the file contents.
manifest.json
{
"name": "Test Extension",
"version": "1.0",
"manifest_version": 2,
"description": "A test extension.",
"background": "background.html",
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery.js","content.js"]
}
],
"permissions": ["tabs", "http://*/", "https://*/"],
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
}
}
background.html
<html>
<head>
<script src="background.js"></script>
</head>
<body>
<h1>Wy</h1>
</body>
</html>
background.js
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
// Chrome 20+
alert(request);
console.log('received in listener');
sendResponse({farewell: "goodbye"});
});
content.js
$(function(){
console.log('start-sending message');
chrome.extension.sendMessage({greeting: "hello"},function(response){alert(response);});
console.log('end-sending message');
});
popup.html
<!doctype html>
<html>
<head>
<title>Getting Started Extension's Popup</title>
</style>
<!-- JavaScript and HTML must be in separate files for security. -->
<script src="jquery.js"></script>
<script src="popup.js"></script>
</head>
<body>
</body>
</html>
popup.js
$(function(){
var str_html = "<tr><td width='60%'>S</td><td width='40%'>15</td></tr><tr><td width='60%'>M</td><td width='40%'>25</td></tr>";
$('#sizes_container').html(str_html);
var bkg = chrome.extension.getBackgroundPage();
console.log(bkg);
});
You're incorrectly mixing the deprecated "background_page" property with the new signature of "background". The correct way to use background pages is:
"background": {
"scripts": ["background.js"]
}
You can completely get rid off your background.html, because it serves no purpose (the content of your <body> is unused) (if you really need it, use "background": {"page": "background.html"}).
About sendRequest, it is indeed deprecated, but not removed (yet).
Regarding your popup page: You don't have any element with ID sizes_container, so you will obviously not see any output.