I am building an extension in Firefox and I wonder if there is a way to know when opening a browser how many instances are open using javascript?
For example I open one instance of Firefox browser I want to get the number of the current instances.
Any ideas?
Found something that may help you:
nsIWindowMediator is a component that keeps track of open windows. It has getEnumerator method that allows you to get all open windows.
If you loop through it, and count them, you get the number of open windows, like so:
var windowMediator = Components.classes["#mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator);
var enumerator = windowMediator.getEnumerator(null);
var count = 0;
while (enumerator.hasMoreElements()) {
var myWindow = enumerator.getNext();
count++;
}
alert(count);
Related
I'm currently coding a bot to do something for me and currently it has to open a large number of tabs every iteration and to make the bot fully automatic I have to find a way to close them all except the original the bot is running from. (The tabs have to be closed before the next iteration or what it's doing fails.)
I found a way to actually do this using a function that would detect the URL and do a specific function for that and then close it. Here's the code...
if (window.location.href.indexOf("https://www.google.com") != -1) {
So this detects that my URL contains a certain string and therefore activates on all pages after this URL. It works for what I want.
Not possible generally via userscripts because modern browsers block the attempts to close tabs/windows (Firefox has a config value to allow it but not all users would be willing to enable it). You will have to convert the userscript to an extension/addon.
In case you don't mind changing the default browser config to allow scripts to close tabs, use GM_setValue to raise a flag that will be periodically checked by your script in other tabs:
var dontCloseMe = false;
setInterval(function() {
var shouldClose = Date.now() - GM_getValue("terminate", 0) < 2 * 100;
if (shouldClose && !dontCloseMe) {
window.close();
}
}, 100);
.................
if (shouldCloseOtherTabs) {
dontCloseMe = true;
GM_setValue("terminate", Date.now());
}
And make sure the // #include actually includes the urls of those other tabs.
I got a chrome extension and in the event of a new tab I want to get the window handle in windows if the current window.
On the event I got the tab object and I got chrome's internal window id but this is not the handle in windows.
chrome.tabs.onCreated.addListener(
function (tab)
{
var intMainWindowHwnd = 0; // how to get it? not tab.windowId…
});
Thanks!
Well, if anyone encounter the same problem, i solved it using a NPAPI Plugin in C++ that get access to win32api...
In Invoke method i've checked for my method (GetProcessId) and got the parent process (since the addon is in a different process):
ULONG_PTR MyAddon::GetParentProcessId() // By Napalm # NetCore2K
{
ULONG_PTR pbi[6];
ULONG ulSize = 0;
LONG (WINAPI *NtQueryInformationProcess)(HANDLE ProcessHandle, ULONG ProcessInformationClass,
PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength);
*(FARPROC *)&NtQueryInformationProcess =
GetProcAddress(LoadLibraryA("NTDLL.DLL"), "NtQueryInformationProcess");
if(NtQueryInformationProcess){
if(NtQueryInformationProcess(GetCurrentProcess(), 0,
&pbi, sizeof(pbi), &ulSize) >= 0 && ulSize == sizeof(pbi))
return pbi[5];
}
return (ULONG_PTR)-1;
}
Then i got the main hwnd of this process and return it to my js addon.
I'm trying to ascertain some way to establish a unique ID for Chrome tabs that meets the following conditions:
Uniquely identifies each tab
Stays the same for a given tab between browser restarts (session-restored tabs)
Stays the same if a tab is closed and then reopened with Undo Closed Tab (Ctrl+Shift+T)
Stays distinct if a tab is duplicated
I've done some rather aggressive research to find a comprehensive solution, but nothing seems to quite do the trick. Here are the methods I have tried, in increasing order of efficacy:
Use Chrome's provided tab.id: does not persist between browser sessions or close/undo-close
Put a GUID in cookies: is not unique per tab, only per domain/URL
Put a GUID in localStorage: persists between browser sessions and close/undo-close, but is not unique per tab, only per domain
Put a GUID in sessionStorage: unique per tab, persists across close/undo-close, unique for duplicated tabs, but is wiped out between browser sessions
Use identifiable webpage document attributes as a unique key: this is the best approach I've found so far. A key can be constructed via a content script from the following values: [location.href, document.referrer, history.length].
Regarding this last approach, the constructed key is unique across all tabs which share a common URL, referrer, and history length. Those values will remain the same for a given tab between browser restarts/session-restores and close/undo-closes. While this key is "pretty" unique, there are cases where it is ambiguous: for example, 3 new tabs opened to http://www.google.com would all have the same key in common (and this kind of thing happens pretty often in practice).
The "put GUID in sessionStorage" method can additionally be used to disambiguate between multiple tabs with the same constructed key for the close/undo-close and duplicated-tab cases during the current browser session. But this does not solve the ambiguity problem between browser restarts.
This last ambiguity can be partially mitigated during session restore by observing which tabs Chrome opens together in which windows, and extrapolating for a given ambiguous key which tab belongs to which window based on the presence of expected 'sibling' tabs (recorded during the previous browser session). As you might imagine, implementing this solution is quite involved and rather dodgy. And it can only disambiguate between same-keyed tabs that Chrome restores into different windows. That leaves same-keyed tabs that restore into the same window as irreconcilably ambiguous.
Is there a better way? A guaranteed unique, browser-generated, per-tab GUID that persists between browser restarts (session restores) and close/undo-close would be ideal but so far I haven't found anything like this.
The question here does most of the discovery work, and the accepted answer basically completes it, but there's a big implementation gap still for people looking to implement something which requires persistent tab IDs. I've attempted to distill this into an actual implementation.
To recap: Tabs can be (almost) uniquely and consistently identified as required by the question by maintaining a register of tabs which stores the following combination of variables in local persistent storage:
Tab.id
Tab.index
A 'fingerprint' of the document open in the tab - [location.href, document.referrer, history.length]
These variables can be tracked and stored in the registry using listeners on a combination of the following events:
onUpdated
onCreated
onMoved
onDetached
onAttached
onRemoved
onReplaced
There are still ways to fool this method, but in practice they are probably pretty rare - mostly edge cases.
Since it looks like I'm not the only one who has needed to solve this problem, I built my implementation as a library with the intention that it could be used in any Chrome extension. It's MIT licensed and available on GitHub for forking and pull requests (in fact, any feedback would be welcome - there are definitely possible improvements).
If I correctly understand your problem, your 5th method should do the trick, but along with these two criteria:
chrome.tabs.windowId (The ID of the window the tab is contained within)
chrome.tabs.index (The zero-based index of the tab within its window)
All these values need to be stored inside your extension. Besides that, you will also have to hook up your extension to chrome.tabs.onUpdated() and updated accordingly, when tabs are being dragged around, moved across owner windows, etc.
Put this as a persistent background script in manifest.json:
"background": {
"scripts": [ "background.js" ],
"persistent": true
},
Here is background.js.
Hopefully the code is self explanatory.
var tabs_hashes = {};
var tabs_hashes_save_queued = false;
function Start(){
chrome.tabs.query({windowType: "normal"}, function(querytabs){
querytabs.forEach(function(tab){
tabs_hashes[tab.id] = GetHash(tab.url);
});
if (localStorage.getItem("tabs_hashes") !== null){
var ref_load = JSON.parse(localStorage["tabs_hashes"]);
var ref_tabId = {};
querytabs.forEach(function(tab){
for (var t = 0; t < ref_load.length; t++){
if (ref_load[t][1] === tabs_hashes[tab.id]){
ref_tabId[ref_load[t][0]] = tab.id;
ref_load.splice(t, 1);
break;
}
}
});
// do what you have to do to convert previous tabId to the new one
// just use ref_tabId[your_previous_tabId] to get the current corresponding new tabId
console.log(ref_tabId);
}
});
}
function SaveHashes(){
if (!tabs_hashes_save_queued && Object.keys(tabs_hashes).length > 0){
tabs_hashes_save_queued = true;
chrome.tabs.query({windowType: "normal"}, function(querytabs){
var data = [];
querytabs.forEach(function(tab){
if (tabs_hashes[tab.id]){
data.push([tab.id, tabs_hashes[tab.id]]);
} else {
data.push([tab.id, GetHash(tab.url)]);
}
});
localStorage["tabs_hashes"] = JSON.stringify(data);
setTimeout(function(){ tabs_hashes_save_queued = false; }, 1000);
});
}
}
function GetHash(s){
var hash = 0;
if (s.length === 0){
return 0;
}
for (var i = 0; i < s.length; i++){
hash = (hash << 5)-hash;
hash = hash+s.charCodeAt(i);
hash |= 0;
}
return Math.abs(hash);
}
chrome.tabs.onCreated.addListener(function(tab){
SaveHashes();
});
chrome.tabs.onAttached.addListener(function(tabId){
SaveHashes();
});
chrome.tabs.onRemoved.addListener(function(tabId){
delete tabs_hashes[tabId];
SaveHashes();
});
chrome.tabs.onDetached.addListener(function(tabId){
SaveHashes();
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo){
if (changeInfo.pinned != undefined || changeInfo.url != undefined){
delete tabs_hashes[tabId];
SaveHashes();
}
});
chrome.tabs.onMoved.addListener(function(tabId){
SaveHashes();
});
chrome.tabs.onReplaced.addListener(function(addedTabId, removedTabId){
delete tabs_hashes[removedTabId];
SaveHashes();
});
Start();
I use array to save data, because in this way I can preserve tabs order, which is unlikely if data would be saved in the object. When loading data after browser's restart, even if url is not unique, I can trust that it will be under some "close enough" index. I would do it more complex, for example reverse check if tab was not found, but this works ok so far.
I have some JScript code (converted from some old VBScript) that starts like this:
var Word = new ActiveXObject("Word.Basic");
Word.FileNew(); // opens new Word document
Word.Insert(IncorrectText);
Word.ToolsSpelling(); // opens spell check behind IE
The idea is to utilize the MS Word spell check for browser use, and it works well in XP, but the spell check box opens in the background in Windows 7 / IE 8 (this question tells me that the problem started in Vista and is probably an OS issue, not a browser or Office issue).
So my question is, how can I bring this window to the foreground? One important note is that the last line, Word.ToolsSpelling();, locks up my script, so anything I do will need to be before that.
I've tried
var wshShell = new ActiveXObject("WScript.Shell");
wshShell.AppActivate("Document1 - Microsoft Word"); // or some other text
before the ToolsSpelling call, but this does not do anything (maybe because the Word document is not actually revealed at this point?). Of course, this will only work if no "Document1" is already opened, so this is a questionable thought to begin with.
Per this answer, I tried using window.blur(); in order to blur IE, but this will only work if the IE window is the only one opened. Maybe there's some way I can loop through all opened windows and apply this?
SetForegroundWindow looked promising, but I don't know how to use it in JSript.
Any ideas?
Note: Browser permissions will be completely open for this site.
Update: Turns out if you use Word.Application, the spell check comes up in front as it should. Only the Word.Basic method has this problem (I don't expect to know why this side of eternity):
var wordApp = new ActiveXObject("Word.Application");
wordApp.Documents.Add();
wordDoc = wordApp.ActiveDocument;
... // safety checks before insertion
wordSelection.TypeText(IncorrectText);
wordDoc.CheckSpelling();
wordApp.Visible = false; // CheckSpelling makes the document visible
You might be able to jigger the window state. When the window is maximized after having been minimized, Windows will stack that in front (zIndex to top).
Something like:
var WIN_MAX = 2;
var WIN_MIN = 1;
var Word = new ActiveXObject("Word.Application");
Word.Visible = true;
// minimize the app
Word.WindowState = WIN_MIN ;
// in 500ms, maximize
setTimeout(function () {
Word.WindowState = WIN_MAX;
}, 500);
The setTimeout call seeks to work around a timing issue; Windows will sometimes "get confused" when a programmatic minimize/maximize happens in immediate succession. You might have to extend that delay a little, test it repeatedly and see what kind of results you get.
I'm trying to do something like this
win = null;
win = window.open('/url/to/link','tab');
win.focus();
but in IE7 it returns me at the line of win.focus(); the error that win is null.
How can I solve it?
Thanks in advance!
You can try adding a slight delay to make sure that the window is open
//win = null; <--useless
win = window.open('/url/to/link','tab');
if(win)window.focus();
else{
var timer = window.setTimeout( function(){ if(win)win.focus(); }, 100 );
}
This day in age, most people avoid pop up windows and use modal layers.
Blockquote <
Return Value
Returns a reference to the new window object. Use this reference to access properties and methods on the new window.
Internet Explorer 7 on Windows Vista: Opening a new window from an application (other than the Internet Explorer process) may result in a null return value. This restriction occurs because Internet Explorer runs in protected mode by default. One facet of protected mode prevents applications from having privileged access to Internet Explorer when that access spans process boundaries. Opening a new window by using this method generates a new process. For more information about protected mode, see Understanding and Working in Protected Mode Internet Explorer. This commonly occurs for applications that host the WebBrowser control.>
Window.Open method documentation
When you launch a popup, give it a variable name:
myWin = window.open(etc)
//in the child window, call window.opener.myFocusFunction()
//in the parent window, use this...
function myFocusFunction(){
myWin.focus();
//myWin.blur();
//uncomment as needed!
}
Have a play, it works for me.