Finding Window and Navigating to URL with Crossrider - javascript

I'm rather new to Javascript and Crossrider. I believe what I'm trying to do is a rather simple thing - maybe I missed something here?
I am writing an extension that automatically logs you into Dropbox and at a later time will log you out. I can log the user into Dropbox automatically, but now my client wants me to automatically log those people out of dropbox by FINDING the open Dropbox windows and logging each one of them out.
He says he's seen it and it's possible.
Basically what I want is some code that allows me to get the active tabs, and set the location.href of those tabs. Or even close them. So far this is what I got:
//background.js:
appAPI.ready(function($) {
// Initiate background timer
backgroundTimer();
// Function to run backround task every minute
function backgroundTimer() {
if (appAPI.db.get('logout') == true)
{
// retrieves the array of tabs
appAPI.tabs.getAllTabs(function(allTabInfo)
{
// loop through tabs
for (var i=0; i<allTabInfo.length; i++)
{
//is this dropbox?
if (allTabInfo[i].tabUrl.indexOf('www.dropbox.com')!=-1)
{
appAPI.tabs.setActive(allTabInfo[i].tabId);
//gives me something like chrome-extension://...
window.alert(window.location.href);
//code below doesn't work
//window.location.href = 'https://www.dropbox.com/logout';
}
}
appAPI.db.set('logout',false);
});
window.alert('logged out.');
}
setTimeout(function() {
backgroundTimer();
}, 10 * 1000);
}
});
When I do appAPI.tabs.setActive(allTabInfo[i].tabId); and then window.alert(window.location.href); I get as address "chrome-extension://xxx" - which I believe is the address of my extension, which is totally not what I need, but rather the URL of the active window! More than that, I need to navigate the current window to the log out page... or at least refresh it. Can anybody help, please?
-Rowan R. J.
P.S.
Earlier I tried saving the window reference of the dropbox URL I opened, but I couldn't save the window reference into the appAPI.db, so I changed technique. Help!

In general, your use of the Crossrider APIs looks good.
The issue here is that you are trying to use window.location.href to get the address of the active tab. However, in the background scope, the window object relates to the background page/tab and and not the active tab; hence you receive the URL of the background page. [Note: Scopes can't directly interactive with each others objects]
Since your objective is to change/close the URL of the active dropbox tab, you can achieve this using messaging between scopes. So, in your example you can send a message from the background scope to the extension page scope with the request to logout. For example (and I've taken the liberty to simplify the code):
background.js:
appAPI.ready(function($) {
appAPI.setInterval(function() {
if (appAPI.db.get('logout')) {
appAPI.tabs.getAllTabs(function(allTabInfo) {
for (var i=0; i<allTabInfo.length; i++) {
if (allTabInfo[i].tabUrl.indexOf('www.dropbox.com')!=-1) {
// Send a message to all tabs using tabId as an identifier
appAPI.message.toAllTabs({
action: 'logout',
tabId: allTabInfo[i].tabId
});
}
}
appAPI.db.set('logout',false);
});
}
}, 10 * 1000);
});
extension.js:
appAPI.ready(function($) {
// Listen for messsages
appAPI.message.addListener(function(msg) {
// Logout if the tab ids match
if (msg.action === 'logout' && msg.tabId === appAPI.getTabId()) {
// change URL or close code
}
});
});
Disclaimer: I am a Crossrider employee

Related

Check if page is loaded from bfcache, HTTP cache, or newly retrieved

the code below checks whether a url is loaded and then logs to the console. I would like to know if there is simple, clean method to check if a page is loaded from bfcache or http cache? Firefox documentation states that the load event should not be triggered if I go from URL A to B and then hit the back button to URL A, but this is not my experience, both load and PageShow is logged regardless, does anyone know why?
var tabs = require("sdk/tabs");
function onOpen(tab) {
tab.on("pageshow", logPageShow);
tab.on("load", logLoading);
}
function logPageShow(tab) {
console.log(tab.url + " -- loaded (maybe from bfcache?) ");
}
function logLoading(tab) {
console.log(tab.url + " -- loaded (not from bfcache) ");
}
tabs.on('open', onOpen);
I am not sure whether there is any purposeful API for that but a workaround that came to mind is to check value of the performance.timing.responseEnd - performance.timing.requestStart. If it is <= 5 then most likely it is HTTP or back-forward cache. Otherwise, it is a download from the web.
A way to recognize a return to the page through a back button instead of opening up a clean URL is to use history API. For example:
// on page load
var hasCameBack = window.history && window.history.state && window.history.state.customFlag;
if (!hasComeBack) {
// most likely, user has come by following a hyperlink or entering
// a URL into browser's address bar.
// we flag the page's state so that a back/forward navigation
// would reveal that on a comeback-kind of visist.
if (window.history) {
window.history.replaceState({ customFlag: true }, null, null);
}
}
else {
// handle the comeback visit situation
}
See also Manipulating the browser history article at MDN.

How to determine if google auth2.signIn() window was closed by the user?

Im implementing auth using this and am currently showing a loading icon in React when a user clicks the button to sign in and the auth2 account selection/login window shows.
However if a user closes the window, there doesnt seem to be any event fired i.e the signIn() function which returns a promise never resolves, I would have thought google would return an error for this promise if the window is closed. As a result there is no way for me to stop showing the loader icon and reshow the login menu.
I was wondering if anyone had a solution for this?
I try to modifiy my code that call Google OAuth 2.0 window.
You only have to add extra AJAX method that cover what is Google OAuth error result.
gapi.auth2.getAuthInstance().signIn()
Change it to this one,
gapi.auth2.getAuthInstance().signIn().then(function(response){
//If Google OAuth 2 works fine
console.log(response);
}, function(error){
//If Google OAuth 2 occured error
console.log(error);
if(error.error === 'popup_closed_by_user'){
alert('Oh Dude, Why you close authentication user window...!');
}
});
That's it...
For more detail about Google OAuth 2.0 information, you can visit this link.
https://developers.google.com/api-client-library/javascript/samples/samples#authorizing-and-making-authorized-requests
Sample code on JavaScript:
https://github.com/google/google-api-javascript-client/blob/master/samples/authSample.html
Although the API provides a mechanism for detecting when the user clicks the Deny button, there is not a built-in way for detecting that the user abruptly closed the popup window (or exited their web browser, shut down their computer, and so on). The Deny condition is provided in case you want to re-prompt the user with reduced scopes (e.g. you requested "email" but only need profile and will let the user proceed without giving you their email).
If the response from the sign-in callback contains the error, access_denied, it indicates the user clicked the deny button:
function onSignInCallback(authResult) {
if (authResult['error'] && authResult['error'] == 'access_denied') {
// User explicitly denied this application's requested scopes
}
}
You should be able to implement sign-in without detecting whether the window was closed; this is demonstrated in virtually all of the Google+ sample apps. In short, you should avoid using a spinner as you're doing and instead should hide authenticated UI until the user has successfully signed in.
It's not recommended you do this, but to implement detection of the pop-up closing, you could do something like override the global window.open call, then detect in window.unload or poll whether the window was closed without the user authenticating:
var lastOpenedWindow = undefined;
window.open = function (open) {
return function (url, name, features) {
// set name if missing here
name = name || "default_window_name";
lastOpenedWindow = open.call(window, url, name, features);
return lastOpenedWindow;
};
}(window.open);
var intervalHandle = undefined;
function detectClose() {
intervalHandle = setInterval(function(){
if (lastOpenedWindow && lastOpenedWindow.closed) {
// TODO: check user was !authenticated
console.log("Why did the window close without auth?");
window.clearInterval(intervalHandle);
}
}, 500);
}
Note that as I've implemented it, this mechanism is unreliable and subject to race conditions.

closing the current tab in a chrome extention

I am writing a chrome extension that when clicked, will close the current tab after a given amount of time.
I am sending a message with the time, from popup.js to background.js. But the tab won't close.
The alert works when I uncomment it, so it seems to be just the remove line. I assume it's something about tab.id.
chrome.extension.onMessage.addListener(
function message(request, sender, callback) {
var ctr = 0;
ctr = parseInt(request.text, 10);
setTimeout(function() {
chrome.tabs.getCurrent(function(tab) {
//window.alert("Working?");
chrome.tabs.remove(tab.id, function(){});
});
}, ctr);
}
);
1.
chrome.extension has no onMessage event. I assume you mean the correct chrome.runtime.onMessage
2.
You have probably misunderstood(*) the purpose of chrome.tabs.getCurrent:
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).
Since, you are calling it from a non-tab context (namely the background page), tab will be undefined.
(*): "misunderstood" as in "not bother to read the manual"...
3.
It is not clear if you want to close the active tab at the moment the timer is set or at the moment it is triggered. (In your code, you are attempting to do the latter, although the former would make more sense to me.)
The correct way to do it:
chrome.runtime.onMessage.addListener(function message(msg) {
var ctr = 0;
ctr = parseInt(msg.text, 10);
setTimeout(function() {
chrome.tabs.query({ active: true }, function(tabs) {
chrome.tabs.remove(tabs[0].id);
});
}, ctr);
});
Also, note that using functions like setTimeout and setInteval will only work reliably in persistent background pages (but not in event pages). If possible, you are advised to migrate to event pages (which are more "resource-friendly"), in which case you will also have to switch to the alarms API.

chrome.windows.getCurrent is not returning the list of opened tabs

var windows = chrome.windows.getCurrent(
function(windows){
try{
// dont really know why this is null. it should be a list of tabs.
if(windows.tabs == null)
alert(windows.type + " " + windows.id);
}
catch(e){
alert(e);
}
});
I am using this code to get all the open tabs in the current window. But the window.tabs is always null even though there are tabs open in the current window. Is there something wrong with the concept of current window.
Could anyone please explain what is it that i am doing wrong.
Thanks.
Looks like the windows object that gets passed to your callback doesn't have a tabs field. Try this code instead:
chrome.windows.getCurrent(function(win)
{
chrome.tabs.getAllInWindow(win.id, function(tabs)
{
// Should output an array of tab objects to your dev console.
console.debug(tabs);
});
});
Also ensure that you have the tabs permission. I also ran this on a background page, so if you're not running it on a background page, you should make sure chrome.tabs is available in your context.

Preventing a Chrome extension's popup.html from opening itself

I'm creating a Chrome extension that has a background.html file which requests information from an API once every minute. Once it receives the information, it messages popup.html with the JSON information with which popup uses to append new HTML elements onto the popup's body.
The problem is background is constantly running (as it should), but it will ping popup even when popup is closed. This causes popup to open itself every minute which is very annoying.
I want to know, is there a way to see if popup is closed and not do anything if that's the case? Or is there another way to prevent popup opening on its own?
Here's the Github repository, but the important parts are highlighted below.
Here's how I'm pinging popup:
// background.js
function sendQuestions()
{
var questions = JSON.parse(db.getItem(storage));
chrome.extension.sendRequest(appid, { 'questions': questions }, function() {});
}
setInterval(sendQuestions, 60e3);
Here's how popup handles it:
// popup.js
chrome.extension.onRequest.addListener(function(request) {
if (request.questions) {
displayQuestions(request.questions);
}
});
function displayQuestions(questions)
{
for (i = 0; i < questions.length; i++) {
var question = questions[i];
var htmlBlock = // ... generate a block of html ...
$('#container').prepend(htmlBlock);
}
}
Open a long lived connection from the popup to the background_page anytime it opens. In the background_page you can check to see if the connection is currently active. If it is pass the necessary messages otherwise wait until the connection is active.

Categories

Resources