I'm developing a chrome app and i'm trying to send a message to an external webpage. In the whole scenario, the external webpage needs to send a message back (but i'm not trying to achieve this yet).
Here is my code:
background.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Prototype</title>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<script src="https://code.jquery.com/jquery.js"></script>
<script src="background.js"></script>
</body>
</html>
background.js
var FileMessage = "Hello!";
var scriptName = "script.js";
var tabID;
//open a new tab with an app
function openApp() {
var url = "link_to_external_webpage_on_personal_server";
var win = window.open(url);
}
//function to run js files inside the extension
function runScript(script){
chrome.tabs.executeScript(null, {file: script});
}
//function to send a message to all tabs
function sendMessage(){
chrome.tabs.query({'active': true}, function(tabs) {
if(tabs.length === 1){
var tab = tabs[0];
//var tabID = tab.id;
chrome.extension.sendMessage(null, {newMessage : FileMessage});
console.log("extension sent a message...");
}
});
}
//main()
$(document).ready(function() {
openApp();
//when a new tab is updated
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
//createEvent();
sendMessage();
}
});
});
/*function createEvent(){
$.event.trigger({
type: "newMessage",
message: "Hello World!"
});
}*/
external js file
$(document).ready(function() {
console.log( "app script is running" );
$(document).on("newMessage", newMessageHandler);
/*document.addEventListener("myEvent",myEventHandler);*/
document.addEventListener("newMessage",myEventHandler);
document.addEventListener('newMessage', function(event) {
console.log("message received...");
}, false);
});
I can see that most of the code is running with the console prints. The only one i'm not receiving is the one saying "message received". I've also tried using events (commented in the code) but i was not successful too.
Does anyone know what i'm doing wrong ?
Thanks in advance for the help !
Related
I just wanted to ask you if it's possible to send a message from content script to the popup script. It works the other way around - from popup to content:
popup.js
let counter = 0;
let userInput = document.getElementById("userInput").addEventListener("click", () => {
counter++
let params = {
active: true,
currentWindow: true
}
chrome.tabs.query(params, gotTabs);
function gotTabs(tabs) {
chrome.tabs.sendMessage(tabs[0].id, counter)
}
});
content.js
chrome.runtime.onMessage.addListener(gotMessage);
function gotMessage(message) {
console.log(message)
}
index.html
<!DOCTYPE html>
<html>
<body>
<h2>Hello there!</h2>
<button id="userInput">Click me!</button>
</body>
<script src="popup.js"></script>
</html>
My question is, how can I send a message from content script to the popup script, if its possible, because when I switch those files, i got errors like:
content.js:14 Uncaught TypeError: Cannot read property 'query' of undefined
at HTMLDocument.myClickHandler
Thanks for your help.
I'm making a Chrome Extension for the first time. When I right click the extension icon and inspect the popup this is the error I'm getting.
Uncaught SyntaxError: Unexpected end of input myextension/popup.html
And the fact that it's failing on an HTML file is making me confused. I looked through about 10 other similar questions and most of the time it's apparently a syntax error in the javascript file. I've linted mine with a couple different linters and still nothing is showing up. Could somebody help me spot a mistake here? It's 62 lines:
function updatePopup(){
listofbad = JSON.parse(localStorage["badguys"]);
$('#dumpster').empty();
var i = 0;
for(i = 0; i < listofbad.length; i = i+1){
$('#dumpster').append( listofbad[i] + "<br>");
}
}
$(document).ready(function(){
if(localStorage["badguys"] != undefined){
var namesthe = JSON.parse(localStorage["badguys"]);
updatePopup();
chrome.tabs.query({
active: true,
currentWindow: true
},
function(tabs) {
/* ...and send a request for the DOM info... */
console.log("Sending message from popup to content");
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', subject: 'DOMInfo', newnames: namesthe}
);
}
);
}
});
function save_options() {
var thenames = [];
if( localStorage["badguys"] != undefined ){
thenames = JSON.parse(localStorage["badguys"]);
}
console.log("JSONParse: " + thenames.toString());
//thenames = ["Aidenator", "Moobot", "Nightbot", "Teamevilmaster"];
var elname = document.getElementById("namebox").value;
if( $.inArray(elname, thenames) > -1 ){
return false;
}
thenames.push(elname);
localStorage["badguys"] = JSON.stringify(thenames);
updatePopup();
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
/* ...and send a request for the DOM info... */
console.log("Sending message from popup to content");
chrome.tabs.sendMessage(
tabs[0].id,
{from: 'popup', subject: 'DOMInfo', newnames: thenames}
);
});
}
document.getElementById('namebutton').addEventListener('click', save_options);
function clearlist() {
localStorage["badguys"] = [];
updatePopup();
}
document.getElementById('clearbutton').addEventListener('click', clearlist );
Here's the small HTML that goes along with it too:
<!doctype html>
<head>
<title>Extension Options</title>
<script src="jquery.js" type="text/javascript"></script>
</head>
<body>
<div id='status'></div>
Annoying person's name:
<input type='text' id="namebox"></input>
<button id="namebutton">Add</button>
<button id="clearbutton">Clear List</button>
<hr>
<center>
<i>List of Removed People:</i>
</center>
<div id="dumpster"></div>
<hr>
<center>
<img src="carlton.jpg" width="50px">
</center>
<script type="text/javascript" src="popup.js"></script>
</body>
</html>
Maybe I've been staring at a screen too long to spot any typos, but if somebody could help me out here, that'd be great. This Chrome Extension business has been quite frustrating.
How to include video recording and downloading in this code, My previous query in this question was solved successfully but now I need to have archiving feature in this solution.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="myPublisherDiv"></div>
<div id="subscriberBucket"></div>
<script src="https://static.opentok.com/webrtc/v2.2/js/opentok.min.js" ></script>
<script type="text/javascript">
var apiKey = "<YOUR API KEY>";
var sessionId = "<YOUR SESSION ID>";
var token = "<YOUR SESSION ID'S TOKEN>";
session = OT.initSession(apiKey, sessionId);
session.connect(token, function (err) {
if (!err) {
session.publish("myPublisherDiv", { mirror: false });
}
});
session.on({
"streamCreated": function (event) {
session.subscribe(event.stream, "subscriberBucket", { width: 600, height: 450 }, { insertMode: "append" });
}
});
</script>
</body>
</html>
And please mention in yur answer if anything is wrong or not in this line
session.on({
"streamCreated": function (event) {
session.subscribe(event.stream, "subscriberBucket", { width: 600, height: 450 }, { insertMode: "append" });
I tested on another OpenTok app and clicked on mute and sound icons but could not reproduce what you are seeing.
I then created a new very simple group video chat app, clicked on mute and sound icons and I also could not reproduce what you are seeing.
I will paste in my group video chat app, you can start from this and slowly add in your own code part by part. Then you will be able to see what is causing your session to disconnect. Here is my simple group video chat app:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="myPublisherDiv"></div>
<div id="subscriberBucket"></div>
<script src="https://static.opentok.com/webrtc/v2.2/js/opentok.min.js" ></script>
<script type="text/javascript">
var apiKey = "<YOUR API KEY>";
var sessionId = "<YOUR SESSION ID>";
var token = "<YOUR SESSION ID'S TOKEN>";
session = OT.initSession(apiKey, sessionId);
session.connect(token, function(err){
if( !err ){
session.publish("myPublisherDiv");
}
});
session.on({
"streamCreated": function(event){
session.subscribe( event.stream, "subscriberBucket", {insertMode: "append"} );
}
});
</script>
</body>
</html>
I'm writing a dummy app to test how works the executeScript() method inside Cordova's InAppBrowser plugin. In particular, I'm trying to inject a javascript code inside one webview.
Here there is my index.html file:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/style.css" />
<script type="text/javascript" src="phonegap.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<title>InAppBrowser Injection Test</title>
</head>
<body>
<div class="app">
<h1>Testing Injection</h1>
<div id="deviceready" class="blink">
<p class="event listening">Starting Mother WebView</p>
<div class="event received">
<p>Device is Ready</p>
</div>
</div>
</div>
<script type="text/javascript">
app.initialize();
</script>
</body>
</html>
And the index.js file
var app = {
initialize: function() {
this.bindEvents();
},
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
onDeviceReady: function() {
app.receivedEvent('deviceready');
var ref = window.open('http://www.example.net', '_blank', 'location=yes ,toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener('loadstart', function(event) { alert('start: ' + event.url); });
ref.addEventListener('loadstop', function() {
//ref.executeScript({ code: "alert('Injected Code')" });
ref.executeScript({ file: "externaljavascriptfile.js" });
showalert();
});
ref.addEventListener('loaderror', function(event) { alert('error: ' + event.message); });
ref.addEventListener('exit', function(event) { alert(event.type); });
},
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
and last the externaljavascriptfile.js
alert('External Injected Code');
If I try to inject javascript code directly (i.e. uncommenting the line "ref.executeScript({ code: "alert('Injected Code')" });" ) all works fine and the alert is triggered after the page load, but if I try to inject an external javascript (i.e. using the line "ref.executeScript({ file: "externaljavascriptfile.js" });", nothing happens.
Am I missing something?
Actually, I think you already know the answer.
executeScript() method run in the child WebView.
ref.executeScript({ file: "externaljavascriptfile.js" });
In your code, executeScript() method is referenced http://www.example.net/externaljavascriptfile.js, not in your script file in /www/js cordova directory. Because executeScript() method injects JavaScript in childview as you know.
You can test the code with below. I've put the file in my website.
//...
onDeviceReady: function() {
var ref = window.open('http://www.haruair.com/', '_blank', 'location=yes, toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener('loadstop', function() {
ref.executeScript({ file: "externaljavascriptfile.js" });
});
},
//...
FYI, if you need to get the data from childview, you can use callback.
//...
var ref = window.open('http://www.haruair.com/', '_blank', 'location=yes, toolbar=yes, EnableViewPortScale=yes');
ref.addEventListener( "loadstop", function() {
ref.executeScript(
{ file:'http://haruair.com/externaljavascriptfile.js' },
function() {
ref.executeScript(
{ code:'getSomething()' },
function(values){
var data = values[0];
alert(data.name);
});
}
);
});
//...
In externaljavascriptfile.js:
var getSomething = function(){
// do something and get the result from childview webpage
return { name : 'foo', age : 12 };
};
Use Ajax to get JS file data then inject it using execute script
$.ajax({
type: "GET",
url: cordova.file.applicationDirectory + "www/js/externalScript.js",
dataType: "text",
success: function (jsCode) {
ref.executeScript({code: jsCode}, function () {
console.log("Code Inserted Succesfully");
});
},
error: function () {
console.log("Ajax Error");
}
});
//ref is reference of inappbrowser
//i.e. var ref = window.open();
//url is url of your local javascript file
With this method you can add a script file which is located in the local APP's sandbox, and not around in the Internet.
Note, you need to cordova-plugin-file:
cordova plugin add cordova-plugin-file
Did you install the inappbrowser plugin?
I have this working in android as follows:
EDIT: Updated for cordova 7
Create the phonegap project
> cordova create JsExec
> cd JsExec
> cordova platform add android
> cordova plugin add cordova-plugin-inappbrowser
Update index.js -here is my onDeviceReady function:
onDeviceReady: function() {
this.receivedEvent('deviceready');
var w = window.open('http://www.example.net','_blank','location=yes');
w.addEventListener('loadstop', function(event) {
w.executeScript({file: "https://s3.amazonaws.com/avvi00/externaljavascriptfile.js"});
});
},
Deploy to my HTC
> cordova run --device
external script file is here
the full working copy of this project is here
regards,
Av
externaljavscriptfile.js is not linked in your html file.
You need to include it with the
<script type="text/javascript" src="path/externaljavascriptfile.js"></script>
tag or to load it dynamically with:
var script = document.createElement('script');
script.async = "async";
script.src = "path/externaljavascriptfile.js";
document.getElementsByTagName("head")[0].appendChild( script );
NOTE: you may need to put your code in a function to execute it.
Hope it works.
I have published a website on a laptop with IIS 7.5 running IE9. When I have the internet plugged in the website works fine. The weird thing is that it will work fine in firefox weither the machine has internet or not.
Some other information that may be helpful.
Running Windows 7 64Bit. Latest version of firefox. IE9.
Not sure what else you may need. I have tried checking IE permissions but there may be something I have missed so any help will be appreciated.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>#ViewBag.Title</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<meta name="viewport" content="width=device-width" />
#*----------------- JQUERY UI for Accordion Starts here-------------------- *#
<link href="../../Content/themes/Blue/jquery-ui-1.9.1.custom.min.css" rel="stylesheet"
type="text/css" />
<script src="../../Scripts/jquery-1.8.2.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-ui-1.9.1.custom.js" type="text/javascript"></script>
#* -----------JQUERY UI for Accordion Ends here--------------------- *# #*----------------- JQUERY UI for Delete Dialog Starts here-------------------- *#
<script src="../../Scripts/external/jquery.bgiframe-2.1.2.js" type="text/javascript"></script>
#* <script src="http://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>*#
<script src="../../Scripts/external/jquery-ui.js">></script>
#*----------------- JQUERY UI for Delete Dialog Ends here-------------------- *#
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#*
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
*# #* ----------- Scripts added for Devexpress but commented because JQUERY UI not working --------------------- *#
#*
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery-1.4.4.js")"></script>
<script type="text/javascript" src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
*# #* ----------- Scripts added for Devexpress ends here--------------------- *#
#Html.DevExpress().GetScripts(
new Script { ExtensionSuite = ExtensionSuite.GridView },
new Script { ExtensionSuite = ExtensionSuite.PivotGrid },
new Script { ExtensionSuite = ExtensionSuite.HtmlEditor },
new Script { ExtensionSuite = ExtensionSuite.Editors },
new Script { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
new Script { ExtensionSuite = ExtensionSuite.Chart },
new Script { ExtensionSuite = ExtensionSuite.Report }
//new Script { ExtensionSuite = ExtensionSuite.Scheduler }
)
#Html.DevExpress().GetStyleSheets(
new StyleSheet { ExtensionSuite = ExtensionSuite.GridView },
new StyleSheet { ExtensionSuite = ExtensionSuite.PivotGrid },
new StyleSheet { ExtensionSuite = ExtensionSuite.HtmlEditor },
new StyleSheet { ExtensionSuite = ExtensionSuite.Editors },
new StyleSheet { ExtensionSuite = ExtensionSuite.NavigationAndLayout },
new StyleSheet { ExtensionSuite = ExtensionSuite.Chart },
new StyleSheet { ExtensionSuite = ExtensionSuite.Report }
//new StyleSheet { ExtensionSuite = ExtensionSuite.Scheduler }
)
#* ---------------------------------JQUERY Scripts for Delete confirmation Starts here --------------------------------*#
<script type="text/javascript">
// increase the default animation speed to exaggerate the effect
$.fx.speeds._default = 500;
$(function () {
$("#dialog").dialog({
autoOpen: false,
show: "blind",
hide: "explode",
width: 250,
resizable: false,
modal: true,
buttons:
{
"Delete": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
//Check data the return from the middle layer, if it is just true, deletion is successful
if (data == '#Boolean.TrueString') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
$("#dialog").dialog("close"); //See it used #dialog instead of (this) because the scope (context) has changed in the "Delete" callback
$(this).empty();
$("#StatusMsg").html("Deleted");
location.reload(); //refreshes the page
}
else {
//Show the errror on the dialog content. Data is used to show the error
//expecting the Error handlers in middle layer will return the meaning ful error message
$("#dialog").html(data);
//Hide confirmation button inorder to show the user to only the content of error in the same
//dialog box and allow to cancel this dialog
$(":button:contains('Delete')").css("display", "none");
$("#StatusMsg").html("Not Deleted");
}
//location.reload();
});
},
"Cancel": function () {
//This reset of the Delete button is need since if it wsas invoked and jumped into show error routine,
// then that routine would have removed the Delete button.
$(":button:contains('Delete')").css("display", "inline");
$(this).dialog("close");
$("#StatusMsg").html("");
}
}
});
var deleteLinkObj;
var deletMsg;
$('a.inputFakeDelete').click(function () {
//Here the message is built using the delete button properties id and name.
//So every page calling this jquery need to have the link button embedded with these properties
//eg: id = Grade, name = the name of the grade from the model
deletMsg = "Are you sure you want to delete this " + this.id;
if (this.name == "") {
}
else {
deletMsg = deletMsg + " '" + this.name + "'" //"Are you sure you want to delete the " + (this).id + " '" + (this).name + "'?";
}
deletMsg = deletMsg + "?"
$("#dialog").html(deletMsg)
deleteLinkObj = $(this); //to use in the dialog javascript
$("#dialog").dialog("open");
return false;
});
});
</script>
#*----------------------------------JQUERY Scripts delete confirmation Ends here --------------------------------*#
#*----------------------------------JQUERY Scripts for record cuirrent filer --------------------------------*#
<script type="text/javascript">
var currentValue = 0;
function handleClick(currentfilter) {
//alert('Old value: ' + currentValue);
//alert('New value: ' + currentfilter.value);
currentValue = currentfilter.value;
//Redirect the page so that will reload with new parameters
window.location = 'http://' + window.location.host + currentValue; //Add 'http://' since host will not include this
}
</script>
#*----------------------------------JQUERY Scripts for record cuirrent filer ends here --------------------------------*#
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
The error page just says that it cannot find a specific webpage. Customer/Delete
I am not sure if this is was the fix for my problem (and it is a little hard to test as the machine is not my own) but later on we reconfigured .net by using aspnet_regiis.exe and the problem looks like it has disapeared.