Chrome: message content-script on runtime.onInstalled - javascript

I'm the maker of an addon called BeautifyTumblr which changes the apperance of Tumblr.
I wish for my Chrome extension to automatically detect when it has been updated and display changelog to the user. I use an event page with the chrome.runtime.onInstalled.addListener hook to detect when an update has occured, retrieve the changelog from a text file in the extension.. this all works fine, then when I want to forward it to my content script via chrome.tabs.sendmessage it just wont work, nothing ever happens, no errors no nothing. I'm stumped.
Any help would be much appreciated!
Event Page:
chrome.runtime.onInstalled.addListener(function (details) {
"use strict";
if (details.reason === "install") {
} else if (details.reason === "update") {
var thisVersion = chrome.runtime.getManifest().version, xmlDom, xmlhttp;
xmlDom = null;
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", chrome.extension.getURL("changelog.txt"), false);
xmlhttp.send(null);
xmlDom = xmlhttp.responseText;
chrome.tabs.query({'url' : 'http://www.tumblr.com/*'}, function (tabs) {
if (tabs.length > 0) {
var mTab = tabs[0].id;
chrome.tabs.update(mTab, {active: true});
setTimeout(chrome.tabs.sendMessage(mTab, {beautifyTumblrUpdate: xmlDom}), 500);
} else {
chrome.tabs.create({'url' : 'http://www.tumblr.com/dashboard'}, function (tab) {
setTimeout(chrome.tabs.sendMessage(tab.id, {beautifyTumblrUpdate: xmlDom}), 500);
});
}
});
}
});
Relevant code in Content Script:
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
"use strict";
window.alert('test');
if (request.beautifyTumblrUpdate) {
window.alert(request.beautifyTumblrUpdate);
} else if (request.beautifyTumblrInstall) {
window.alert(request.beautifyTumblrInstall);
}
}
);

I am also seeing the same thing. I am not a 100% sure but I think this happens because chrome shuts off connection between background page and "old" content scripts the moment the extension is updated. There's more info here in this bug : https://code.google.com/p/chromium/issues/detail?id=168263

simple, use the following code in background,
chrome.runtime.onInstalled.addListener(function(details){
if(details.reason == "install"){
chrome.tabs.create({ url: chrome.extension.getURL('welcome.html')});
}
});

Related

Load another html page without changing URL

I have some problem with page load on desktop browser and mobile browser. In this case I have 4 html page one is home.html, second is home-mobile.html, third is product.html and fourth is product-mobile.html. My problem is I don't know to switch the html page if opened in mobile browser. For the example is when I open www.example.com in desktop the page will call home.html but when I open www.example.com in mobile the page will call home-mobile.html and so with product page, when I open www.example.com/product in desktop it will call product.html but when I open www.example.com/product in mobile it will call product-mobile.html. The point is how could I open one link and it will detect opened in desktop browser or mobile browser and call different html page.
Which I have been done now but still not working is :
<script>
window.mobilecheck = function() {
var check = false;
if(window.innerWidth<768){
check=true;
}
return check;
}
if(window.mobilecheck()){
window.location.href="home-mobile.html";
}
else {
window.location.href="home.html";
}
</script>
But with that script the URL was changing and not be the same.
Please anyone know how to do this could help me. Thanks.
This script allows you to change the page content without redirecting the browser.
window.mobilecheck = function() {
var check = false;
if (window.innerWidth < 768) {
check = true;
}
return check;
}
if (window.mobilecheck()) {
$.ajax({
'type': 'POST',
'url': 'home_mobile.html',
'data': postData,
'success': function(response) {
$("html").html(response);
}
});
}
modify the code as you need.
If your device mobile it will automatically redirect on mobile page. Simple use this code. No need for else condition. just check mobile device.
if ($(window).width() < 767) {
function getMobileOperatingSystem() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
"Android"
if (/windows phone/i.test(userAgent)) {
return "Windows Phone";
}
if (/android/i.test(userAgent)) {
return "Android";
}
if (/iPhone|iPod/.test(userAgent) && !window.MSStream) {
return "iOS";
}
return "unknown";
}
if(getMobileOperatingSystem()){
window.location="\home-mobile.html";
}
}
Let's say your page is home.html.
And when the page is loaded, you can run a script to detect client type( desktop or mobile), then send an Ajax call to corresponding page to get the content you want.
Then when the Ajax call returned, you can simply replace current content with the returned value.
In this way, your URL will not change at all, and the content can change according to current client type.
home.html:
<html>
<head>
<script language="javascript">
function loadContent(){
var clientType
//your code to get client type here
//Below block to get Ajax client object according to your browser type
var XHTTP;
try
{
//For morden versions Internet Explorer
XHTTP = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (ex)
{
try
{
try
{
//For old versions Internet Explorer
XHTTP=new ActiveXObject("Microsoft.XMLHTTP");
}
catch(exxx)
{
XHTTP = new XMLHttpRequest("Msxml2.XMLHTTP");
}
}
catch(exx)
{
try
{
//For browsers other than Internet Explorer
XHTTP= new XMLHttpRequest();
}
catch(eexx)
{
//This means ActiveX is not enabled.
//To enabled go to your browser settings and enabled the ActiveX.
alert("Not Supported, It might be previous version browser");
}
}
}
if(clientType=="mobile"){
XHTTP.open("GET","/home_mobile.html");
}else{
XHTTP.open("GET","/home_desktop.html")
}
XHTTP.onreadystatechange= function()
{
if (XHTTP.readyState==4)
{
var result=XHTTP.responseText.toString();
document.getElementById("content").innerHTML=result;
}
}
//This finlly send the request.
XHTTP.send(null);
}
</script>
</head>
<body onload="javascript:{loadContent();}">
<div id="content"></div>
</body>
</html>
This script will change the html content of a current page with requested page html without changing url. (AJAX)
var xhr = new XMLHttpRequest(); // Create XMLHttpRequest object
xhr.onload = function() { // When response has loaded
// The following conditional check will not work locally - only on a server
// if(xhr.status === 200) { // If server status was ok
document.getElementsByTagName("html")[0].innerHTML= xhr.responseText; // Update
//}
};
xhr.open('GET', 'html u want to replace ', true); // Prepare the request
xhr.send(null); // Send the request
});

Open chrome extension page programmatically in same tab as website

I am making an chrome-extension-based editor, and I want the user to be able to open a file within the extension when they receive a link like this: http://myeditor.com/link.html?file=xxxx
When going to that website I would like that:
if the person opening the url has the extension, open chrome-extension://blahblah/?file=xxx
else show a read-only version of the file and a link to install the extension.
Now to do that, I have in the link.html file a script that looks like this:
if (window.chrome) {
if (chrome.app.getDetails() === null) {
chrome.runtime.sendMessage(chromeId, { message: "isInstalled" }, function (reply) {
if (reply) {
chrome.runtime.sendMessage(chromeId, { gotoUrl: document.location.search });
}
});
}
}
and in the extension's background.html:
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
if (request) {
if (request.message) {
if (request.message == "isInstalled") {
sendResponse(true);
}
}
if (request.gotoUrl) {
var url = chrome.extension.getURL(request.gotoUrl);
chrome.tabs.create({url: url}); // how do I open this in the same tab rather than create a new tab?
}
}
return true;
});
The issue is that the code creates a new tab, is there a way I can open the extension page in the same tab as the page I called it from?
Actually chrome.tabs.update instead of chrome.tabs.create works fine...

Chrome Extension: WebQL database is not appearing in Inspector

I am trying to create database and tables in background.js file of Chrome but somehow it's not being created. When I see in Chrome Inspector > Resources > WebSQL, I find nothing. Code is given below:
function fetchData(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost/php/fetch.php", true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
// JSON.parse does not evaluate the attacker's scripts.
var resp = xhr.responseText;
if(resp != null) {
var json = JSON.parse(resp)
console.log(resp);
var data = json['data'];
if(data != null) {
openDatabase('documents', '1.0', 'my storage', 5*1024*1024, function (db) {
alert('Called'); //This is not being called.
});
//var dbConnection = openDbConnect();
//createTable(dbConnection);
//Code below is called
for(var a=0;a <= data.length;a++) {
alert(data[a].title);
}
}
}
}
}
xhr.send();
}
Update
I guess it's being created: My Extension ID is bkjajbjnoadlhnhmfekipifehbhgidpg
In ~/Library/Application Support/Google/Chrome/Default/databases I find:
chrome-extension_bkjajbjnoadlhnhmfekipifehbhgidpg_0
But it's weird I can't see it in Inspector.
Update #2
Turns out that like pages, WebSQL is not visible across Chrome. It shows Db to the page which is visited. Now I am getting no idea how to excess chrome related Db in Viewer.
To access the inspector for the background page of your app, go to Menu>Settings>Extensions and make sure it's in Developer Mode. It should have a link to inspect the background page of your app in there. It will open up in a new window.

Passing message from content script in Chrome extensions

I want to run a content script to identify the first image that links somewhere and return the link to the background script. But I can't pass any messages between them, and I don't know why. Much of the code is comment, I'm trying to simply test if the content script is executing by telling it to change the first header to "test" (since the only thing I can do without messages is change a page's HTML and CSS). The code follows:
EDIT: full updated code
Background script:
chrome.browserAction.onClicked.addListener(function () {
chrome.tabs.query({active:true, currentWindow:true}, function(tabs)
{
chrome.tabs.executeScript(tabs[0].id, {file:"content.js"}, function ()
{
console.log("sending first time");
console.log(tabs[0].id);
chrome.tabs.sendMessage(tabs[0].id,{test: "test"}, function (response)
{
if (undefined == response)
{
console.log ("first one didn't work");
chrome.tabs.sendMessage(tabs[0].id, {test: "test"}, function (response)
{
console.log(response.test);
});
}
});
});
});
});
Content Script:
chrome.runtime.onMessage.addListener( function (msg, sender, sendResponse)
{
/*var test1 = document.getElementsByTagName("h1")[0];
test1.innerHTML="test";*/
sendReponse({test: "123"});
/*var parentList =document.getElementsByTagName("a");
var link = "";
var child;
for (var i=2; i<parentList.length;i++)
{
child=parentList[i].firstChild;
if ("IMG"==child.nodeName)
{
link=parentList[i].href;
break;
}
}
teste1.innerHTML=link;
var answer = new Object();
Answer.link = link;
teste1.innerHTML=answer.link;
sendResponse({messager:answer});*/
});
I was testing the extension at the extension page itself. But it seems you can't inject javascript in it (probably because it is a browser's settings page). It worked nicely on other pages.

login into the site with my javascript

i'm trying to login into the site with the following javascript. But, i'm loading only the complete page. I'm developing windows 8 app
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/home/home.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function (element, options) {
// TODO: Initialize the page here.
document.getElementById("bt_login").addEventListener("click", login, false);
}
});
})();
function login() {
var xhrDiv = document.getElementById("xhrReport");
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = dataLoaded;
xhr.open("POST", "http://www.160by2.com", true, <username>, <password>);
xhr.send();
function dataLoaded() {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// OK
xhrDiv.innerHTML = window.toStaticHTML("response:" + xhr.responseText);
} else {
// not OK
xhrDiv.innerText = "failure";
}
}
};}
I want to dsiplay in xhrdiv.innerHTML as "LOGIN SUCCESS" or "LOGIN ERROR"
EDIT:
I tried the following code:
iframe = document.getElementById("ifra_op");
iframe.setAttribute("src", "http://www.160by2.com/index");
document.getElementById("op").appendChild(iframe);
iframe.contentWindow.document.getElementById("MobileNoLogin") = "<mobno>";
iframe.contentWindow.document.getElementById("LoginPassword") = "<pass>;
iframe.contentWindow.document.getElementsByName("LoginForm").click();
But, there is an error. It says "Javascript run time error:math is undefined"
"math" comes from the website. I don't know how to handle this. Also, the permission is denied. Why is that so?
You need to make sure you have a service (something like a web service) in the remote server to process the request.
In here what you can do is.
Create an iframe and set the src to 160by2;
Access the webpage using iframe.contentwindow, inject your code to fill up the forms and trigger the submit button.
Parse the received html to verify your login.
Use jquery , makes life easier.
var iframe = $("#ifra_op");
$(iframe).attr("src", "http://www.160by2.com/index");
$(iframe).attr("onload","submitForm();");
function submitForm(){
$(iframe.contentWindow.document).find("#MobileNoLogin").val("9999");
$(iframe.contentWindow.document).find("#LoginPassword").val("pass");
$('#button').click();
}

Categories