Open chrome extension page programmatically in same tab as website - javascript

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...

Related

How to keep popup open when launchWebAuthFlow starts?

I am running launchWebAuthflow in background.js and successfully retrieving the Oauth2 token in the call back. However, the extension pop closes during this flow and thus it doesn't receive my response. When I have dev-tools open on the pop-up, it stays open and everything works as expected. It seems that somehow launchWebAuthFlow is taking focus from the popup and subsequently closing it even though it should be running in the background. Any advice would be much appreciated. See code in background.js below
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request.message === "getAuth") {
chrome.identity.launchWebAuthFlow({
url: authUrl.href,
interactive: true,
},
(redirectUrl) => {
if (redirectUrl) {
// The ID token is in the URL hash
const urlHash = redirectUrl.split("#")[1];
const params = new URLSearchParams(urlHash);
const jwt = params.get("id_token");
console.log(jwt);
sendResponse({
token: jwt
});
}
}
}
return true;
}

How to run callback function from content script after loading page ? chrome extension

I want to run a callback function from content script after tab loading new page .
Here is my code :
content_script.js
chrome.runtime.onMessage.addListener(function(request, sender, callback) {
if (request.id == "content_script") {
// open google.com
chrome.runtime.sendMessage({
"id" : "openUrl",
"url" : "https://google.com"
}, function(response) {
});
// call background script
// go to the claim code page
chrome.runtime.sendMessage({
"id" : "background"
}, function() {
alert("test");
});
}
});
background.js
chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
if (msg.id == "openUrl") {
var tabId = sender.tab.id;
var url = msg.url;
openUrl(tabId, url);
} else if (msg.id == "background") {
setTimeout(function() {
sendResponse();
}, 5000);
}
});
function openUrl(tabId, url) {
chrome.tabs.update(tabId, {
url : url,
active : false
}, function() {
console.log("open tab url callback");
});
};
I also uploaded the source code to google drive, you can download it using the bellow link :
https://drive.google.com/open?id=15zSn40z4zYkvCZ8B-gclzixvy6b0C8Zr
as you can see the alert test don't show !
However if I remove the code which open new url , then alert ("test") appear !
I am not sure why ! but it looks like javascript lost the reference to the call back function when I open new url .
How can I solve the problem ? what's the correct way ?
Thank you
The sendResponse function becomes invalid after the message callback returns, unless you return true from the event listener to indicate you wish to send a response asynchronously. (https://developer.chrome.com/extensions/runtime#event-onMessage)
Add return true; in background.js to make this handler asynchronous.
Now you get an error Attempting to use a disconnected port object in the sendResponse(); call of background.js, and yes, that's a result of the page navigating away and losing the context that the content script was running in.
There's no way to make this work: The context in which you wanted to call alert() simply doesn't exist anymore.
Try using chrome.tabs.sendMessage instead. But this means you have to set up the listener at the top level, and not inside of any callback. Message passing is hard.

Execute content script within new tab - chrome extentions

I'm trying to create a chrome extension that scrapes some content from a particular website and then opens a new tab and does stuff with the scraped data.
Below is a test I made to see how I might do this. Unfortunately I can't seem to execute the newtab-script.js file as I get this error:
Unchecked runtime.lastError while running tabs.executeScript: Cannot
access contents of url
"chrome-extension://FAKEIDgfdsgfdsgfdsgdsgfdsgFAKEID/newpage.html".
Extension manifest must request permission to access this host.
at Object.callback (chrome-extension://FAKEIDgfdsgfdsgfdsgdsgfdsgFAKEID/background.js:43:25)
websitescrape.js
var button = document.createElement("button");
button.classList.add("web-scrape");
button.innerHTML = "scrape web";
document.querySelector('.placeIWantToPutButton').appendChild(button);
button.addEventListener('click', scrapeData);
function scrapeData(){
//do website scraping stuff here...
var fakedata = [{test:"data1"},{test:"data2"}];
//send scraped data to background.js
chrome.runtime.sendMessage({setdata: fakedata}, function(tab){
//callback
});
}
background.js
var dataTempStorage = [];
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request.setdata) {
dataTempStorage = request.setdata;
chrome.tabs.create({
'url': chrome.extension.getURL('newpage.html')
}, function(tab) {
chrome.tabs.executeScript(tab.id, {
file:chrome.extension.getURL("newtab-script.js")});
});
}
if (request == "getdata") {
sendResponse({data: dataTempStorage});
}
});
newtab-script.js
chrome.runtime.sendMessage("getdata", function (response) {
doStuff(response.data);
});
function doStuff(){
//Do staff on newpage.html with data scraped from original page
}
newpage.html
// page ready to be filled with awesome content!
Cause: content scripts can't be injected into extension pages with chrome-extension:// scheme.
Solution: since you have control over that html page just reference the content script file explicitly.
newpage.html:
<script src="newtab-script.js"></script>
</body>
</html>
And don't use executeScript.

chrome extension, pass data from content to background

I've created a chrome extension that consists of manifest.json, content.js and background.js. in content.js, I'm extracting the current tab's URL and in background.js, I'm opening a new tab. what I want to do, which doesn't work is to pass the URL from content and append it to the URL that I'm calling in background.
content.js:
chrome.extension.onMessage.addListener(function(request, sender, sendResponse)
{
if(request.greeting=="gimmieyodatas")
{
var output ="URL=";
//check for the character '?' for any parameters in the URL
var paramIndex = document.URL.indexOf("?");
//if found, eliminate the parameters in the URL
if (paramIndex > -1)
{
output += document.URL.substring(0, paramIndex);
};
sendResponse({data: output});
}
else{
sendResponse({});
}
});
background.js:
var output2;
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.sendMessage(tab.id, {greeting:"gimmieyodatas"}, function(response) {
output2 = response.data;
});
});
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.create({url: "http://www.google.com?" + output2}, function(tab) {
chrome.tabs.executeScript(tab.id, {file: "content.js"}, function() {
sendMessage();
});
});
});
When I run the extension from an open tab, it opens google on a new tab, but it doesn't append the current tab's URL in google URL, meaning the 'output' data does not get passed to the background.js. What am I doing wrong?
The problem is that you are not telling the background page to send a message when a new tab is opened. The call to chrome.tabs.getSelected only happens once when the extension is first run -- it does not happen every time a new tab is opened.
You're on the right track by using the background page as an intermediary between the two content pages, but I suggest a different approach:
Load the content script every time a new tab is opened, via the manifest file:
"content_scripts": [
{
"matches" : [
"<all_urls>"
],
"js" : [
"content.js"
]
}
],
Use a much simpler content script that just sends a message to the background with the current URL page as soon as it loads:
(content.js)
var paramIndex = document.URL.indexOf('?');
if (paramIndex > -1) {
chrome.runtime.sendMessage({output2: 'URL=' + document.URL.substring(0, paramIndex)});
}
When the background page receives the message it saves the URL to a global variable:
(background.js)
var output2;
chrome.extension.onMessage.addListener(function(request, sender, sendResponse) {
output2 = request.output2;
});
You can then load that URL when the action button is clicked:
(background.js)
chrome.browserAction.onClicked.addListener(function() {
chrome.tabs.create({url: "http://www.google.com?" + output2});
});

Chrome: message content-script on runtime.onInstalled

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')});
}
});

Categories