URL bar not updated in Chrome after Backbone routing - google-chrome

I have a Backbone application which, at one point, opens a new tab in the browser. After the execution in the new tab is complete a javascript will be triggered (in that new tab) to trigger routing in the opener window. Javascript code looks like this:
window.onunload = window.onbeforeunload = function(e){
opener.router.navigate("start",{trigger: true});
};
window.close();
This works great, the 'start' route is executed and the correct result is shown in all browsers (including Chrome). But in Chrome, the url bar is not updated with the new url (eg. ../something#start), instead the original url for the opening window remains in the address bar.
In IE and Firefox the url bar shows the correct url. Is there some way to achieve this behaviour in Chrome also?
Any input appreciated!

Instead of trying to make a call to the router directly from the tab that's about to be closed, have you tried triggering a Backbone event (which the "opener window" would be listening to) instead?
So change:
window.onunload = window.onbeforeunload = function(e){
opener.router.navigate("start",{trigger: true});
};
window.close();
to:
window.onunload = window.onbeforeunload = function(e){
Backbone.trigger('routeChange');
};
window.close();
And include a listener to the routeChange event in the "opener window's" view with a callback function which executes router.navigate():
opener.listenTo(Backbone, 'routeChange', function(e) {
opener.router.navigate('start',{trigger: true});
});
Let me know if that helps.

Related

Open a html page located inside Firefox web extension

I have some html files inside a Firefox web extension which I want to open on Browser Action event (Click on the tool bar icon). The way I was doing it in chrome was:
var appId = chrome.app.getDetails().id;
var tabUrl = "chrome-extension://" + id + "/src/index.html";
chrome.windows.getCurrent(function (currentWindow) {
chrome.tabs.create({
url: tabUrl
});
});
What I am trying to do fir firefox is:
//firefox doesnt support chrome.app, so I have hard coded the app id in manifest under applications.gecko.id
var id = chrome.runtime.getManifest().applications.gecko.id;
var tabUrl = "moz-extension://" + id + "/src/index.html";
//I have tried chrome-extension:// also above
browser.tabs.create({
url: tabUrl,
active:true
});
Its just opening a new tab with the url but the page is not loading. Any suggestion on what I am doing wrong
In Firefox the URL is constructed as moz-extension://[some GUID here]/, not chrome-extension://[extension ID here]. The GUID is not predictable.
The right way to get the URL for Firefox (and Chrome) is to use chrome.runtime.getURL:
chrome.tabs.create({
url: chrome.runtime.getURL('src/index.html')
});
Another method that works for getting an absolute URL is (only when the code runs in the context of your extension page, not in content scripts):
chrome.tabs.create({
url: location.origin + '/src/index.html')
});
You can also pass a relative URL to chrome.tabs.create:
chrome.tabs.create({
url: '/src/index.html'
});
Note that when you use relative URLs, make sure that you specify the full path (starting with /). This is because Firefox and Chrome resolve relative URLs differently. For example, if you have a script running in a page in a subdirectory "/html/" in your add-on, then Firefox will resolve the URL relative to the subdirectory, whereas Chrome will resolve the URL relative to the extension root. So:
// Running at moz-extension://[guid]/html/page.html
// or at chrome-extension://[id]/html/page.html
chrome.tabs.create({url: 'newpage.html'});
// Firefox: Opens moz-extension://[guid]/html/newpage.html
// Chrome: Opens chrome-extension://[id]/newpage.html
chrome.tabs.create({url: '/newpage.html'});
// Firefox: Opens moz-extension://[guid]/newpage.html
// Chrome: Opens chrome-extension://[id]/newpage.html

Opening a PDF Blob in a new Chrome tab (Angular 2)

I am loading a PDF as follows (I am using Angular 2, but I am not sure that this matters..):
//Inside a service class
downloadPdf = (id): Observable<Blob> => {
let headers = new Headers();
headers.append("Accept", "application/pdf");
return this.AuthHttp.get(this.pdfURL + id, {
headers: headers,
responseType: ResponseContentType.Blob
}).map(res => new Blob([res.blob()], {type: "application/pdf"}));
}
//Inside a click handler
this.pdfService.downloadPdf(this.id).subscribe((data: Blob) => {
let fileURL = window.URL.createObjectURL(data);
window.open(fileURL);
});
This code runs nicely in Firefox. In Chrome, a new tab briefly flashes open and closes. When I debug and I manually put surf to the object URL, Chrome can open it just fine.
What am I doing wrong here?
The opening of a new tab got blocked by an adblocker.
It can not work, new popup will be blocked by browser, because of it was created from callback which is not a trusted event, to make it work it must be called directly from click handler, or you have to disable bloking popups in your browser.
Chrome will only allow this to work as wanted if the ajax call returns in less than a second. More there

Open extension popup when click on context menu

I have to make an extension that when clicked on text in the context menu, in callback opens the extension menu popup.
chrome.runtime.onInstalled.addListener(function() {
var context = "selection";
var title = "Google for Selected Text";
var id = chrome.contextMenus.create({"title": title, "contexts":["selection"],
"id": "context" + context});
});
// add click event
chrome.contextMenus.onClicked.addListener(onClickHandler);
// The onClicked callback function.
function onClickHandler(info, tab) {
var sText = info.selectionText;
var url = "https://www.google.com/search?q=" + encodeURIComponent(sText);
//what i have put here to open extension popup
};
In this case, when I click on the menu I open a new tab with this search.
There is no way of opening the default browser action popup programmatically. A work around is use content scripts to open a modal or a lightbox and show the contents of your popup.
Another way would be - within the clickhandler of your context menu item, create a new tab and make it inactive and then pass that tab to chrome.windows.create api to create a new popup window.
chrome.tabs.create({
url: chrome.extension.getURL('popup.html'),
active: false
}, function(tab) {
// After the tab has been created, open a window to inject the tab
chrome.windows.create({
tabId: tab.id,
type: 'popup',
focused: true
});
});
It is just a work around. Hope it helps.
It is now possible to open a browser action popup programmatically from inside the handler for a user action.
browser.menus.create({
id: "open-popup",
title: "open popup",
contexts: ["all"]
});
browser.menus.onClicked.addListener(() => {
browser.browserAction.openPopup();
});
You can read more about it here.
Edit:
This feature is only available as of Firefox 57. In Chrome, it is only available in the dev channel.
Sources: chrome/common/extensions/api/_api_features.json - chromium/src - Git at Google
Unfortunately, it cannot be done.
Chrome API doesn't provide a method to open extension popup programmatically. The Chromium team rejected the feature request for such an option with an explanation that:
The philosophy for browser and page action popups is that they must be
triggered by user action.
Here's the source.
You can use the chrome.window API (documentation here).
What you want is something like this :
chrome.windows.create({
url : "http://yourPopupUrl.com"
focused : true
type : "popup"});
This will open a new windows in popup mode (without the top menu bar) and load the "http://yourPopupUrl.com".

chrome extension API for refreshing the page

Is there an API to programmatically refresh the current tab from inside a browser action button? I have background page configured, which attaches a listener via:
chrome.browserAction.onClicked.addListener(function(tab) { ... });
So the callback function retrieves a reference to the tab that it was clicked from, but I don't see an API anywhere to refresh/reload that tab.
I think what you're looking for is:
chrome.tabs.reload(integer tabId, object reloadProperties, function callback)
Check out tabs API() documentation for more information.
The API for chrome.tabs.getSelected(), which the accepted answer uses, has been deprecated. You should instead get the current tab and reload it using something like the following:
chrome.tabs.query({active: true, currentWindow: true}, function (arrayOfTabs) {
var code = 'window.location.reload();';
chrome.tabs.executeScript(arrayOfTabs[0].id, {code: code});
});
Or perhaps:
chrome.tabs.query({active: true, currentWindow: true}, function (arrayOfTabs) {
chrome.tabs.reload(arrayOfTabs[0].id);
});
I had no real luck with the second version, though other answers seem to suggest it should work. The API seems to suggest that, too.
I recommend using chrome.tabs.executeScript to inject javascript that calls window.location.reload() into the current tab. Something like:
chrome.tabs.getSelected(null, function(tab) {
var code = 'window.location.reload();';
chrome.tabs.executeScript(tab.id, {code: code});
});
Reference here
More specifically:
chrome.tabs.getSelected(null, function(tab) {
chrome.tabs.reload(tab.id);
});
You can also use this:
chrome.tabs.reload(function(){});
reload function params: integer tabId, object reloadProperties,
function callback
Reference: http://developer.chrome.com/extensions/tabs.html#method-reload
if you want to reload all the tabs which have loaded completely and are active in their window
chrome.tabs.query({status:'complete'}, (tabs)=>{
tabs.forEach((tab)=>{
if(tab.url){
chrome.tabs.update(tab.id,{url: tab.url});
}
});
});
you can change the parameter object to fetch only active tabs as {status:'complete', active: true} refer to query api of chrome extensions
Reason for not using chrome.tabs.reload :
If the tab properties especially the tab.url have not changed, tab does not reload. If you want to force reload every time, it is better to update the tab URL with its own tab.url which sends the event of the change in property and tab automatically reloads.

Chrome extension: how to constantly check URLs on new tabs and then respond with an action for certain URLs?

Hi—I'm not a student or a programmer by trade, but I'm trying to knock up a quick prototype to get an idea across. I've cobbled together some code from other StackOverflow questions, and I've almost got what I need, but I'm having trouble with one thing: the extension will run exactly once, but no more, until I refresh the extension via chrome://extensions. I'm guessing there's something wrong with the element of this program that listens for a new URL, but I can't figure out how to keep that element listening constantly. This code runs in background.js right now, though I've also tried it in background.html.
Basically, I'd like the extension to check the URL of a tab any time the user visits a new page (either by typing the URL herself or clicking through to one), and, if the URL appears in the plugin's internal URL list, to pop up a short notification. I have this so far:
// Called when the url of a tab changes.
// So we can notify users
var notification = webkitNotifications.createNotification(
'48.png',
'Alert!'
);
// Called when the url of a tab changes.
function checkForValidUrl(tab) {
// Compare with a the URL
if (tab.url.match(/google/)) {
//then
notification.show();
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tab);
}
});
chrome.tabs.onSelectionChanged.addListener(function(tabId, selectInfo){
chrome.tabs.getSelected(null, function(tab){
checkForValidUrl(tab);
});
});
I fixed this after hacking it around a little bit -- I don't really have the vocabulary to explain what I did but I thought I'd post the code in case someone else has the same (simple) problem later.
function checkForValidUrl(tabId, changeInfo, tab) {
var notification = webkitNotifications.createNotification(
'48.png',
'Alert!',
'Watch out for your privacy!'
);
// Compare with the URL
if (tab.url.match(/google/)) {
//then
notification.show();
}
};
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
if(changeInfo.status == "loading") {
checkForValidUrl(tabId, changeInfo, tab);
}
});