Chrome extension: get current tab url - google-chrome

I am trying to get current tab url in Chrome extenstion.
All sources says that I need "chrome.tabs.query({active: true;})"
Truth is, that chrome.tabs.query can only be executed in background, and for background active tab is ALWAYS and ONLY "chrome://extensions".
Is there any way to get ACTUAL active tab's url?

Found solution.
As I previously mentioned, "chrome.tabs.query({active: true;})" can only run from background.js, and background.js's active tab is always browser's extensions page, so it's useless.
According to security policies we need instead to waste tons of PC's recources and do something like this:
in client.js:
function getcururl(){
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.extension.getURL('gturl.js');
s.onload = function() {
window.postMessage({ type: "gtcrurl", value: cururl }, "*");
this.remove();
};
(document.head || document.documentElement).appendChild(s);}
document.addEventListener('DOMContentLoaded', getcururl());
in gturl.js:
var cururl = window.location.host;
Now we can do in popup.js something like:
var crurl = "empty";
window.addEventListener("message", function(event) {
if(event.data.type === 'gtcrurl') {
window._test = event.data.value;
console.log(event.data.value);
crurl = event.data.value;
}}, false);

Related

chrome.omnibox ceases working after period of time. Begins working after restarting extension

I'm leveraging Google Chrome's omnibox API in my extension.
Current users, including myself, have noticed that the omnibox ceases responding entirely after an undetermined state change or a period of time lapsing. Typing the word to trigger entering into "omnibox" stops having any effect and the URL bar does not shift into omnibox mode.
Restarting Google Chrome does not fix the issue, but restarting my plugin by unchecking and then re-checking the 'enabled' checkbox on chrome://extensions does resolve the issue.
Does anyone have any suggestions on what to investigate? Below is the code used. It is only loaded once through my permanently persisted background page:
// Displays streamus search suggestions and allows instant playing in the stream
define([
'background/collection/streamItems',
'background/model/video',
'common/model/youTubeV2API',
'common/model/utility'
], function (StreamItems, Video, YouTubeV2API, Utility) {
'use strict';
console.log("Omnibox LOADED", chrome.omnibox);
var Omnibox = Backbone.Model.extend({
defaults: function () {
return {
suggestedVideos: [],
searchJqXhr: null
};
},
initialize: function () {
console.log("Omnibox INITIALIZED");
var self = this;
chrome.omnibox.setDefaultSuggestion({
// TODO: i18n
description: 'Press enter to play.'
});
// User has started a keyword input session by typing the extension's keyword. This is guaranteed to be sent exactly once per input session, and before any onInputChanged events.
chrome.omnibox.onInputChanged.addListener(function (text, suggest) {
// Clear suggested videos
self.get('suggestedVideos').length = 0;
var trimmedSearchText = $.trim(text);
// Clear suggestions if there is no text.
if (trimmedSearchText === '') {
suggest();
} else {
// Do not display results if searchText was modified while searching, abort old request.
var previousSearchJqXhr = self.get('searchJqXhr');
if (previousSearchJqXhr) {
previousSearchJqXhr.abort();
self.set('searchJqXhr', null);
}
var searchJqXhr = YouTubeV2API.search({
text: trimmedSearchText,
// Omnibox can only show 6 results
maxResults: 6,
success: function(videoInformationList) {
self.set('searchJqXhr', null);
var suggestions = self.buildSuggestions(videoInformationList, trimmedSearchText);
suggest(suggestions);
}
});
self.set('searchJqXhr', searchJqXhr);
}
});
chrome.omnibox.onInputEntered.addListener(function (text) {
// Find the cached video data by url
var pickedVideo = _.find(self.get('suggestedVideos'), function(suggestedVideo) {
return suggestedVideo.get('url') === text;
});
// If the user doesn't make a selection (commonly when typing and then just hitting enter on their query)
// take the best suggestion related to their text.
if (pickedVideo === undefined) {
pickedVideo = self.get('suggestedVideos')[0];
}
StreamItems.addByVideo(pickedVideo, true);
});
},
buildSuggestions: function(videoInformationList, text) {
var self = this;
var suggestions = _.map(videoInformationList, function (videoInformation) {
var video = new Video({
videoInformation: videoInformation
});
self.get('suggestedVideos').push(video);
var safeTitle = _.escape(video.get('title'));
var textStyleRegExp = new RegExp(Utility.escapeRegExp(text), "i");
var styledTitle = safeTitle.replace(textStyleRegExp, '<match>$&</match>');
var description = '<dim>' + video.get('prettyDuration') + "</dim> " + styledTitle;
return {
content: video.get('url'),
description: description
};
});
return suggestions;
}
});
return new Omnibox();
});
As far as I'm aware the code itself is fine and wouldn't have any effect on whether I see omnibox or not.
You can find full source code here: https://github.com/MeoMix/StreamusChromeExtension/blob/master/src/js/background/model/omnibox.js

Chrome API : Reloading current tab with a url using method in Content.js

I want to reload the page with url by scanning content of it. I designed this method in javascript to see if the url has specific stirng in it
Content.Js
function init() {
var d = document.location.href;
d = toggleDevMode(d);
return d;
}
function toggleDevMode(url) {
var hasDevModeOn = '?core.apexpages.devmode.url=1';
if (url.indexOf(hasDevModeOn) != -1) {
//toggle
url = url.substring(0, url.lastIndexOf(hasDevModeOn));
} else if (url.indexOf("salesforce.com") == -1) {
url = url + hasDevModeOn;
} else {
url = url;
}
return url;
}
Functionality I want
I want if user click on icon, it run the script calling method I defined in content.js onClick Event and checks url.
Based on Logic I defined here, url will be modified.
I want reload the tab with modified url. I tried this piece of code
chrome.browserAction.onClicked.addListener(function (activeTab) {
var newURL = init();
chrome.tabs.create({
url: newURL
});
});
But it doesn't work. Please advice how can I call these method onclick event
You don't need a content script to do this. Discard your init function. Put your toggleDevMode function together with the following code in a background script. Make sure your manifest specify the activeTab permission.
chrome.browserAction.onClicked.addListener(function (activeTab) {
var newURL = toggleDevMode(activeTab.url);
chrome.tabs.update({
url: newURL
});
});
EDIT: Replace your current permissions section from your manifest by the following:
"permissions": [
"activeTab"
],

Sending message from popup.js in Chrome extension to background.js

What is the proper way to send a message (and get a response) to background.js from popup.js in a Chrome extension? Every method I try ends up with an error that:
"Port: Could not establish connection. Receiving end does not exist."
I would prefer to use chrome.extension.sendMessage() over chrome.extension.connect() with port.postMessage(), but neither method seems to have worked.
What I am trying to do is wire a button in the popup.html to call into some javascript in popup.js which calls back to background.js in an effort to get info about the currentTab() that was topMost (ie:to get the current URL string to show in the popup.html)
Right now in popup.js (wired to the action of the button) I have:
function getURL()
{
chrome.extension.sendMessage({greeting: "GetURL"},
function(response) { tabURL = response.navURL });
$("#tabURL").text(tabURL);
}
In background.js I have:
chrome.extension.onMessage.addListener( function(request,sender,sendResponse)
{
if( request.greeting == "GetURL" )
{
var tabURL = "Not set yet";
chrome.tabs.getCurrent(function(tab){
tabURL = tab.url;
});
sendResponse( {navURL:tabURL} );
}
}
Any ideas?
Just to clarify, we talking about communication between popup page from browserAction and background script?
Anyway you have quite a few errors in your code.
First your totally ignore the fact that all callbacks in chrome api are asynchronous.
In background page
var tabURL = "Not set yet";
chrome.tabs.getCurrent(function(tab){
tabURL = tab.url;
}); //this will be invoked somewhere in the future
sendResponse( {navURL:tabURL} );
//navUrl will be always Not set yet because callback of getCurrent hasn't been called yet
Same in popup.js
chrome.runtime.sendMessage({greeting: "GetURL"},
function(response) { tabURL = response.navURL });//callback will be invoked somewhere in the future
$("#tabURL").text(tabURL)//tabURL will display something totally different from what you have been expected
Second error is that chrome.tabs.getCurrent doesn't give you the current tab selected by user in main window. The docs says:
Gets the tab that this script call is being made from. May be
undefined if called from a non-tab context (for example: a background
page or popup view).
So you will get undefined for all of your requests, because you call it in background page. What you need to do is to use method chrome.tabs.query to obtain currently active tabs.
So after fixing all problems new code should look something like this:
background.js
chrome.runtime.onMessage.addListener( function(request,sender,sendResponse)
{
if( request.greeting === "GetURL" )
{
var tabURL = "Not set yet";
chrome.tabs.query({active:true},function(tabs){
if(tabs.length === 0) {
sendResponse({});
return;
}
tabURL = tabs[0].url;
sendResponse( {navURL:tabURL} );
});
}
}
popup.js
function getURL() {
chrome.runtime.sendMessage({greeting: "GetURL"},
function (response) {
tabURL = response.navURL;
$("#tabURL").text(tabURL);
});
}

How to include a link in the HTML5 notification?

I would like to be able to set a link/permalink to each notification, so when user clicks on it; then he is taken to the permalink location,
I've seen this answer which has a solution that's a little bit different because static link is used,
I would like to, somehow:
var noti = window.webkitNotifications.createNotification(
'http://funcook.com/img/favicon.png',
'HTML5 Notification',
'HTML5 Notification content...',
'http://mycustom.dynamic.link.com/' /* invented code */
)
noti.onclose = function(){ alert(':(') };
noti.onclick = function(){
window.location.href = $(this).url; /* invented code */
};
noti.show();
Any chance? (I really don't like the static html file solution... I would like to keep this syntax)
How about something like this?
var createNotificationWithLink = function(image, title, content, link) {
var notification = window.webkitNotifications.createNotification(image, title, content);
notification.onclose = function() {
alert(':(');
};
notification.onclick = function() {
window.location.href = link;
};
return notification;
};
Now you can call createNotificationWithLink whenever you want to create a notification:
var noti = createNotificationWithLink(
'http://funcook.com/img/favicon.png',
'HTML5 Notification',
'HTML5 Notification content...',
'http://mycustom.dynamic.link.com/'
);
noti.show();
You can also move noti.show(); into the createNotificationWithLink function if you like (notification.show();). I don't know if you want the notification to be shown automatically when you create it...
You can pass a data property that you can read from within the onclick event handler as e.target.data.
var notification = new window.Notification("Hello!",
{
body: "Hello world!",
data: "https://www.example.com/?id=" + 123
});
notification.onclick = function(e) {
window.location.href = e.target.data;
}
noti.onclick = function() {
window.open("http://www.stackoverflow.com")
};
More on how to use window.open: http://www.w3schools.com/jsref/met_win_open.asp4
HTML5 Notification Resource: http://www.html5rocks.com/en/tutorials/notifications/quick/ (If this doesn't answer you're question)
For Each one you could have:
var noti1 = window.webkitNotifications.createNotification(
'http://funcook.com/img/favicon.png',
'HTML5 Notification',
'HTML5 Notification content...',
var noti2 = window.webkitNotifications.createNotification(
'http://funcook.com/img/favicon.png',
'HTML5 Notification #2',
'HTML5 Notification #2 content...',
etc
and then
noti1.onclick = function() {
window.open("http://www.stackoverflow.com")
};
noti2.onclick = function() {
window.open("http://www.example.com")
};
hope that helps :)
You can add the url as a property to 'noti', then call that property with this.yourpropertyname
example:
noti.myurl = 'http://stackoverflow.com';
...
noti.onclick = function(){
window.location.href = this.myurl;
};
hope this helps.
For anyone, who needs to open a new browser window(tab), but does not want the parent window(tab) to be replaced and focused upon notification click, this code snippet will do the trick:
var notification = new window.Notification("Hello!", {
body: "Hello world!",
data: "https://www.google.com/"
});
notification.onclick = function(event) {
event.preventDefault(); //prevent the browser from focusing the Notification's tab, while it stays also open
var new_window = window.open('','_blank'); //open empty window(tab)
new_window.location = event.target.data; //set url of newly created window(tab) and focus
};

Get current tab and pass it to variable in a Chrome Extension

I'm trying to create a function that returns the current tab url:
function tabURL() {
var url="";
chrome.tabs.getSelected(null, function(tab) {url = tab.url;});
return url;
}
When I use:
chrome.tabs.getSelected(null, function(tab) {alert(tab.url);});
Chrome shows the url, but if I use my function inside the chrome console, the function returns "".
Is there a way to pass the tab.url to a variable and then return this variable?
chrome.tabs.getSelected is asynchronous. That means that when the callback function is called, return url "has already occurred".
You've got two options to achieve the desired effect.
Properly rewrite your code, to correctly implement the asynchronous aspect (the exact details depends on your extension's implementation).
Note that getSelected has been deprecated and replaced with chrome.tabs.query since Chrome 16.
Maintain a hash with the current URLs using chrome.tabs.onUpdated (add tabID + URL), chrome.tabs.onRemoved (to remove obsolete entries) and chrome.tabs.onActivated (to set the current active tab).
Code for 2:
// Our hash
var tabIdToURL = {};
var currentTabId = -1;
// Add changes to the hash (tab creation, tab's page load)
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
tabIdToURL[tabId] = tab.url; // also available as tab.id and changeInfo.url
});
// Remove entries from closed tabs
chrome.tabs.onRemoved.addListener(function(tabId) {
delete tabIdToURL[tabId];
});
// Set the ID of the current active tab
chrome.tabs.onActivated.addListener(function(activeInfo) {
currentTabId = activeInfo.tabId;
});
// Usage, based on the question's function
function getURL() {
return tabIdToURL[currentTabId] || '';
}