chrome extension. JS not running [duplicate] - javascript

This question already has answers here:
onclick or inline script isn't working in extension
(5 answers)
Closed 5 years ago.
I am trying to create a Chrome extensions that perform an Autocomplete functio on an input field.
First please have a look and the function code on a normal HTML page
<!DOCTYPE html>
<html>
<head>
<title>Testing autocomplete</title>
<script>
var people = ['Fabio', 'Marco', 'Pietro', 'Kucio', 'Pato'];
function matchPeople(input) {
var reg = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i');
return people.filter(function(person) {
if (person.match(reg)) {
return person;
}
});
}
function changeInput(val) {
var autoCompleteResult = matchPeople(val);
var text = "";
var i;
for (i = 0; i < autoCompleteResult.length; i++) {
text += autoCompleteResult[i] + "<br>";
}
document.getElementById("result").innerHTML = text;
}
</script>
</head>
<body>
<input type="text" onkeyup="changeInput(this.value)">
<div id="result"></div>
</body>
</html>
Now, if we run this code on any webpage it works just fine.
The issue I am having is to move the above functions in a Chrome Extension.
I have my manifest.json here:
{
"name": "AutoComplete UZ",
"version": "1.0",
"description": "Provides with a small popup window with the AutoComplete function with UZ internal emails.",
"browser_action": {
"default_popup": "popup.html",
"default_title": "UZ AutoComplete"
},
"content_scripts": [
{
"matches" : ["http://*/*", "https://*/*"],
"css": ["style.css"],
"js" : ["popup.js"]
}
],
"manifest_version": 2
}
My popup.html file here:
<!DOCTYPE html>
<html>
<head>
<title>UZ AutoComplete</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="popup.js"></script>
</head>
<body>
<h1>UZ AutoComplete</h1>
<h3>Type email address</h3>
<input id="amount" type="text" onkeyup="changeInput(this.value)" placeholder="your email">
<div id="result"></div>
</body>
</html>
and my popup.js file here:
var people = [
'Fabio',
'Marco',
'Pietro',
'Kucio',
'Pato'
];
function matchPeople(input) {
var reg = new RegExp(input.split('').join('\\w*').replace(/\W/, ""), 'i');
return people.filter(function(person) {
if (person.match(reg)) {
return person;
}
});
}
function changeInput(val) {
var autoCompleteResult = matchPeople(val);
var text = "";
var i;
for (i = 0; i < autoCompleteResult.length; i++) {
text += autoCompleteResult[i] + "<br>";
}
document.getElementById("result").innerHTML = text;
}
If I pack the above files and create an Extension, the above code will not work. I see the popup.html input field but the functions that make the magic won't trigger and I do not understand why.
I do not think I need an event.js page to run the above simple functions but please let me know the best approach for this. Hope I was clear enough on what I am trying to achieve.
Any help is more than welcome stackoverflowers!

Google Chrome extensions do not allow inline Javascript.
You'll need to to add an event listener in your popup.js instead.
document.querySelector('#amount').addEventListener('keyup', function() {
//get input's value and call your functions here
});

Related

Wondering how to add label or text to html page based on input?

I'm making a chrome extension and im wondering how to add a label based on an input box triggered by a button.
I have tried many approaches like changing innerHTML of label i have used .value but nothing has worked. Here is code:
popup.js:
let AddNote = document.getElementById("AddNote");
let input = document.getElementById("input");
function addnote() {
var elem = document.createElement('label');
elem.innerHTML = input.value;
document.getElementsByTagName('body')[0].appendChild(elem);
}
chrome.storage.sync.get("note", ({ note }) => {
AddNote.addEventListener("click", addnote);
});
popup.html:
<html>
<head>
<link rel="stylesheet" href="button.css">
</head>
<body>
<form>
<button id="AddNote">+</button>
<input type="text" id="input"></input>
<label id="label"></label>
</form>
</body>
</html>
background.js:
let note = '';
chrome.runtime.onInstalled.addListener(() => {
chrome.storage.sync.set({ note });
console.log('Set note variable to empty.', `note: ${note}`);
});
manifest.json:
{
"name": "name",
"description": "desc.",
"version": "1.0",
"manifest_version": 3,
"service_worker": "background.js",
"action": {
"default_popup": "popup.html"
}
}
let AddNote = document.getElementById("addNotes");
AddNote.addEventListener("click", function () {
let elem = document.createElement('label')
let space = document.createElement('br')
elem.innerHTML = input.value;
document.getElementsByTagName('body')[0].appendChild(space);
document.getElementsByTagName('body')[0].appendChild(elem);
});
/* chrome.storage.sync.get("note", ({ note }) => {
AddNote.addEventListener("click", addnote);
});
*/
<html>
<head>
<link rel="stylesheet" href="button.css">
</head>
<body>
<button id="addNotes">+</button>
<input type="text" id="input">
<label id="label"></label>
</body>
</html>
What I added/changed
1. The input tag is empty, which means that the closing tag isn't required. And so I removed it's closing from your HTML.
2. I commented around `chrome.storage.sync.get()`, since this will only work if stack snippet was an extension, which it isn't.
3. With the help of `br` tags, each time before adding the label I added a br, just so all the labels won't appear on the same row. You can remove that if you don't need it.
The main problem
In HTML5, If you have a form tag without an `action` attribute then the data will be sent to its own page. That being said, when clicking the `+` button the page would redirect to itself (looks like a refresh), resulting in the wrong conclusion thinking your code didn't work. I removed the `form` tag from your HTML.

extract text from pdf in chrome extensions

I am developing a chrome extensions. What i want to realize is that the popup can display the text from pdf. I have searched the PDF.js and write the following code in backgroud.js of chrome extensions to test:
‘use strict’;
var pdf = PDFJS.getDocument('http://www.pacer.gov/documents/pacermanual.pdf');
var pdf = PDFJS.getDocument('pacermanual.pdf');
pdf.then(function(pdf) {
var maxPages = pdf.pdfInfo.numPages;
for (var j = 1; j <= maxPages; j++) {
var page = pdf.getPage(j);
// the callback function - we create one per page
var processPageText = function processPageText(pageIndex) {
return function(pageData, content) {
return function(text) {
// bidiTexts has a property identifying whether this
// text is left-to-right or right-to-left
for (var i = 0; i < text.bidiTexts.length; i++) {
str += text.bidiTexts[i].str;
}
if (pageData.pageInfo.pageIndex ===
maxPages - 1) {
// later this will insert into an index
console.log(str);
}
}
}
}(j);
var processPage = function processPage(pageData) {
var content = pageData.getTextContent();
content.then(processPageText(pageData, content));
}
page.then(processPage);
}
});
The manifest is shown as follow:
{
"name": "englishhelper",
"version": "0.0.1",
"description": "",
"permissions": [
"tabs", "http://*/*", "https://*/*"
],
"background":{
"script":["background.js","PDF.js"]
},
"browser_action":{
"default_icon":"icon_png",
"default_popup":"popup.html"
},
"manifest_version": 2
}
The popup.html is shown as follow:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="popup.css">
<title></title>
</head>
<body>
<script src="background.js"></script>
<script src="PDF.js"></script>
</body>
</html>
The console shows that "PDFJS is not defined". The "PDF.js" has been included in popup.html. Is it possible that chrome extension use PDF.js?
Wrong load order. (Do we have a canonical question for that?)
background.script or content_scripts[i].js key in the manifest is an array, in other words an ordered list.
Scripts are loaded and executed in the sequence defined there; you need to make sure libraries are loaded before they are used.
In your case, you need to swap them around:
"background":{
"script": ["PDF.js", "background.js"]
},
Same applies to the order of <script> tags in HTML, for instance in your popup.html

Script is working in jsfiddle but not in browser

I'm trying to create an extension for Chrome Browser. It should include options where the behaviour of an newly created tab can be chosen (e.g. opening the tab in background or in foreground). The setting should be stored with localStorage.
As I'm new in programming JavaScript, I took the example code from http://developer.chrome.com/extensions/options and tried to customise it. This is what I have so far, and it is working (which means the chosen radio button is saved when page is reloaded) in jsfiddle: http://jsfiddle.net/yczA8/
I was really happy to see it working. But after having created and loaded the Chrome extension, it wasn't working any more. Also opening the html-File in Chrome Browser doesn't show the same behaviour as it does in jsfiddle. Why not? Where's the problem?
This is my popup.html:
<!DOCTYPE html>
<html>
<head>
<style>
body {
min-width: 200px;
min-heigth: 100px;
overflow-x: hidden;
}
</style>
<script src="popup.js"></script>
</head>
<body>
<h3>Neuer Tab im:</h3>
<form method="post">
<input type="radio" name="tabVerhalten" value="tabVordergrund" />Vordergrund
<br />
<input type="radio" name="tabVerhalten" value="tabHintergrund" />Hintergrund
</form>
<div id="status"></div>
<button id="save">Save</button>
</body>
</html>
This one is popup.js:
// Saves options to localStorage.
function save_options() {
var tabVerhalten1 = document.getElementsByName('tabVerhalten')[0].checked;
var tabVerhalten2 = document.getElementsByName('tabVerhalten')[1].checked;
var tabVerhaltenIndex;
if (tabVerhalten1)
tabVerhaltenIndex = 0;
else if (tabVerhalten2)
tabVerhaltenIndex = 1;
localStorage.setItem("tabVerhalten", tabVerhaltenIndex);
// Update status to let user know options were saved.
var status = document.getElementById("status");
status.innerHTML = "Änderungen gespeichert.";
setTimeout(function () {
status.innerHTML = "";
}, 750);
}
// Restores select box state to saved value from localStorage.
function restore_options() {
var storedVal = localStorage.getItem("tabVerhalten");
if (!storedVal) {
return;
}
document.getElementsByName('tabVerhalten')[storedVal].checked = true
}
restore_options();
document.addEventListener('DOMContentLoaded', restore_options);
document.querySelector('#save').addEventListener('click', save_options);
and finally the manifest.json:
{
"manifest_version": 2,
"name": "TEST",
"version": "1.0",
"author": "STM",
"description": "Description",
"permissions": ["contextMenus", "tabs"],
"background": {"scripts": ["script.js"]},
"icons": {"16": "16.png", "48": "48.png", "128": "128.png"},
"browser_action": {"default_icon": "48.png", "default_popup": "popup.html"}
}
Try doing this instead:
document.addEventListener("DOMContentLoaded", function() {
restore_options();
}, false);
I MADE THE FOLLOWING CHANGES:
I removed method="post"
I moved <script src="popup.js"></script> after all the other script
I changed the parameters for the addEventListener() method
HERE ARE THE CHANGED SCRIPTS
popup.html:
<!DOCTYPE html>
<html>
<head>
<style>
body {
min-width: 200px;
min-heigth: 100px;
overflow-x: hidden;
}
</style>
</head>
<body>
<h3>Neuer Tab im:</h3>
<form>
<input type="radio" name="tabVerhalten" value="tabVordergrund" />Vordergrund
<br />
<input type="radio" name="tabVerhalten" value="tabHintergrund" />Hintergrund
</form>
<div id="status"></div>
<button id="save">Save</button>
<script src="popup.js"></script>
</body>
</html>
popup.js
// Saves options to localStorage.
function save_options() {
var tabVerhalten1 = document.getElementsByName('tabVerhalten')[0].checked;
var tabVerhalten2 = document.getElementsByName('tabVerhalten')[1].checked;
var tabVerhaltenIndex;
if (tabVerhalten1)
tabVerhaltenIndex = 0;
else if (tabVerhalten2)
tabVerhaltenIndex = 1;
localStorage.setItem("tabVerhalten", tabVerhaltenIndex);
// Update status to let user know options were saved.
var status = document.getElementById("status");
status.innerHTML = "Änderungen gespeichert.";
setTimeout(function () {
status.innerHTML = "";
}, 750);
}
// Restores select box state to saved value from localStorage.
function restore_options() {
var storedVal = localStorage.getItem("tabVerhalten");
if (!storedVal) {
return;
}
document.getElementsByName('tabVerhalten')[storedVal].checked = true
}
restore_options();
document.addEventListener('DOMContentLoaded',function() {restore_options();}, false);
button_thing = document.querySelector('#save').addEventListener('click',function() {save_options();}, false);
Your problem is, in JSFiddle you are running the JS-code onLoad and in your files you are running the JS-code in the header.
If you change it in your JSFiddle, it's no longer working as you can see here: JSFiddle.
So, what can you do to solve this issue?
There are different ways, I'll recommend to load your JS-code on load, like JSFiddle does. To do this, add the onload event to your body tag. There you call a function named 'loadMyScript();' or something like this:
<body onload="loadMyScript();">
For the next step, you have the choice: You can put your whole code in the loadMyScript() function or you import your script with the loadMyScript() function. I didn't test those ways, so I can't tell you which one is working better or which one is simpler but you should try the import-script-way first, because I think this could avoid issues.
Little example of the import-script-way:
<head>
<script>
function loadMyScript() {
var js = document.createElement("script");
js.type = "text/javascript";
js.src = "popup.js";
document.body.appendChild(js);
}
</script>
<!-- YOUR HTML HEAD HERE -->
</head>
<body onload="loadMyScript();">
<!-- YOUR HTML BODY HERE -->
</body>

chrome extension and javascript submitting form

I recently started learning chrome ext. And I'm running in to this problem.
Basically I'm just trying to convert a string into corresponding number.
for example a=1, b=2, c=3... and so on.
So if I'm trying to use a html form to get the input string, then using onclick on the submit button, I want my javascript file to convert the string to the number and print out the value on that same input text box.
This is my current code, it is working fine if I get the input by using prompt.
My question is how do I call the onclick because manifest version 2 is restricting inline js.
Manifest
{
"name": "String converter",
"version": "1.0",
"manifest_version": 2,
"description": "Convert string to number",
"browser_action": {
"default_icon": "icon.ico",
"default_popup": "popup.html"
}
}
Popup.html:
<!doctype html>
<html>
<head>
<title>Convert string</title>
<style>
body {
min-width:160px;
overflow-x:hidden;
}
</style>
<script src="popup.js"></script>
</head>
<body>
<input type="text" id="result" />
<!--I need the button here-->
</body>
</html>
popup.js (i just copy and paste this from a tutorial and modify it)
var req = new XMLHttpRequest();
req.open(
"GET",
"http://api.flickr.com/services/rest/?" +
"method=flickr.photos.search&" +
"api_key=90485e931f687a9b9c2a66bf58a3861a&" +
"text=hello%20world&" +
"safe_search=1&" + // 1 is "safe"
"content_type=1&" + // 1 is "photos only"
"sort=relevance&" + // another good one is "interestingness-desc"
"per_page=20",
true);
req.onload = test;
req.send(null);
function test(){
var s=prompt("enter string");
var result ="";
for(var i =0; i<3; i++){
if(s.charAt(i) == "a"){
result += "1"
}
else if(s.charAt(i) == "b"){
result += "2"
}
else if(s.charAt(i) == "c"){
result += "3"
}
document.getElementById("result").value = result;
}
Thank you!
place this button code where u want button:
<button id='sbmt'>Submit</button>
and in popup.js add these lines to listen to click events of above button.
function myAlert(){
alert('Button Clicked');
}
document.addEventListener('DOMContentLoaded', function () {
document.getElementById('sbmt').addEventListener('click', myAlert);
});

javascript objects cant see each other? :: google chrome extension

i have two files
one called stats.js
one called storage.html
in stats.js in contains
var stats = {
myFunc : function() {
//do something
}
}
in storage.html I have
<html>
<head>
<script src="stats.js"></script>
<script>
$(document).ready(function() {
stats.myFunc();
});
</script>
</head>
</html>
But I get
Uncaught TypeError: Cannot call method 'myFunc' of undefined
Update
Ok so that was a really simplified example.
The basics of it are,
This is a google chrome extension, So you will see some code specific to that.
Here is the literal pages concerned:
Popup.html
<html>
<head>
<title>Extension</title>
<script src="http://code.jquery.com/jquery-1.4.2.min.js"></script>
<script src="js/popup.js"></script>
<script src="js/statsapi.js"></script>
<link type="text/css" rel="stylesheet" href="css/popup.css" />
</head>
<body>
<div id="content">
</div>
</body>
</html>
popup.js
$(document).ready(function() {
if(background.storage.get('firstRun') == null)
background.initialize();
if(background.storage.get('metaExpire') >= Date.parse(Date()))
background.updateMeta();
$('#content').append(read_object(stats.getMetaData()));
});
function read_object(object){
var $obj = $('<div />');
for(var o in object) {
$obj.append(o+' : ');
if(typeof(object[o]) == 'object' && object[o] != null)
$obj.append(read_object(object[o]));
else
$obj.append(object[o]+'<br />');
}
return $obj;
}
Manifest.json
{
"name": "Halo Reach: Stats",
"description": "This extension allows you to keep track of your own, and your friends Halo Reach Stats.",
"version": "1.0.0.1",
"permissions": [
"http://www.bungie.net/"
],
"icons": {
"128": "images/logo/logo128.jpg",
"64": "images/logo/logo64.jpg",
"32": "images/logo/logo32.jpg",
"16": "images/logo/logo16.jpg"
},
"browser_action": {
"default_title": "Open Stats",
"default_icon": "images/logo/logo32.jpg",
"popup": "popup.html"
},
"background_page": "background.html"
}
statsapi.js
var background = chrome.extension.getBackgroundPage();
var apikey = background.storage.get('apikey');
var gamertage = background.storage.get('gamertag');
var page = '0';
var stats = {
getMetaData : function() {
var url = 'http://www.bungie.net/api/reach/reachapijson.svc/game/metadata/'+apikey;
console.log(url);
$.ajax({
url: url,
success: function(data) {
return data;
}
});
},
meta : {
read : function(param) {
var meta = background.storage.get('metaData');
}
}
};
Background.html
<html>
<head>
<script src="js/statsapi.js"></script>
<script>
var storage = {
set : function (key, value) {
window.localStorage.removeItem(key);
window.localStorage.setItem(key, value);
},
get : function (key) {
return window.localStorage.getItem(key);
},
clear : function () {
window.localStorage.clear();
}
};
function updateMeta() {
var meta = stats.getMetaData();
if(meta['status'] == 0){
storage.set('metaData', JSON.stringify(meta));
storage.set('metaExpire', Date.parse(Date())+900000);
}
}
function initialize() {
storage.set('apikey', '***');
storage.set('gamertag', 'The Hailwood');
updateMeta();
}
</script>
</head>
</html>
When the extension is invoked it calls popup.html
and the document ready javascript is invoked.
The check for first run fails,
so it calls initialize() in background.html
But this is where the error occurs.
the actual error is
Uncaught TypeError: Cannot call method 'getMetaData' of undefined.
So why can it not see the stats class?
its not a script include problem as if the path is wrong for the statsapi.js I get
Uncaught ReferenceError: stats is not defined.
The issue seems to be with the var stats {} as if under that I have a function called test() I can call that fine :/
Hmm,
is there an issue because it is an external stylesheet?
I suspect the error lies somewhere else - these are my examples:
mark#localhost:~/ccsite$ cat cat.js
var stats = {
myFunc : function() {
alert('wtf');
}
}
mark#localhost:~/ccsite$ cat hat.htm
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="cat.js"></script>
<script>
$(document).ready(function() {
stats.myFunc();
});
</script>
</head>
</html>
Viewing hat.htm in either FF, IE6 or Chrome produces the alert, 'wtf'. As written you'd get $ is undefined, since it's not including jQuery of course, so I added that.
So, your problems likely are elsewhere. I assume this is a simplified example - what else is going on in your page?
This is because there is some syntax error in your code. I had same problem. I opened my background.html page in fire fox with fire-bug plug-in enabled. Fire-bug console should me the error, I fixed and it is working now.
I have suspicions that it's because you include js/statsapi.js script into both your popup and background page, so it gets confused which stats you are referring to as you have 2 of them in the popup - one included through script tag and another one loaded from background page after you call chrome.extension.getBackgroundPage()

Categories