How to get window handle (int) from chrome extension? - javascript

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.

Related

Can the property search function in a browser's console be replicated programatically?

In the browser dev tools console you can search for things.
In this instance it is some information held in a script variable and is in JSON format.
So I have some questions:
1 - Is there a way to replicate this console search in javascript?
2 - Where is this information actually held, is it in memory? Some of the details in that JSON have been updated by javascripts after page load, it is no longer the same version that you can get from the page source HTML.
You could try using a Proxy object to monitor (and intercept) changes made to the object.
digitalData = new Proxy(digitalData, {
set: function (target, key, value) {
target[key] = value;
// updated object
console.log({ target });
return true;
}
);
I have achieved this by using the appropriate browser document window;
function GetDocWindow()
{
var document, window;
document = Sys.Browser().Page("*").contentDocument
// Check if the document.parentWindow property is available
if (aqObject.IsSupported(document, "parentWindow")){
window = document.parentWindow //ie browser
Log.Message("Document type in use is 'parentWindow'")
}
// Check if the document.defaultView property is available
else if (aqObject.IsSupported(document, "defaultView")){
window = document.defaultView //chrome browser
Log.Message("Document type in use is 'defaultView'")
}
else
Log.Error("Unknown browser that doesn't support document.parentWindow or document.defaultView.");
return window
}
the "aqObject" is native to smartbear's testComplete software but hopefully this will help along anyone that is looking for something similar as I had trouble getting this answer.

Detect if console/devtools is open in all browsers

I'm trying to create a script which will run when any browser console is opened or closed. Is there any way to detect if the browser console in all browsers (Firefox/IE/Chrome/Safari/Opera) is open or not via JavaScript, jQuery, or any other client-side script?
If you are willing to accept an interference for the user,
you could use the debugger statement, as it is available in all major browsers.
Side note: If the users of your app are interested in console usage, they're probably familiar with dev tools, and will not be surprised by it showing up.
In short, the statement is acting as a breakpoint, and will affect the UI only if the browser's development tools is on.
Here's an example test:
<body>
<p>Devtools is <span id='test'>off</span></p>
<script>
var minimalUserResponseInMiliseconds = 100;
var before = new Date().getTime();
debugger;
var after = new Date().getTime();
if (after - before > minimalUserResponseInMiliseconds) { // user had to resume the script manually via opened dev tools
document.getElementById('test').innerHTML = 'on';
}
</script>
</body>
devtools-detect should do the job. Try the simple demo page.
devtools-detect → detect whether DevTools is open, and its orientation.
Supported Browsers:
DevTools in Chrome, Safari, Firefox & Opera
Caveats:
Doesn't work if DevTools is undocked (separate window), and may show a false positive if you toggle any kind of sidebar.
I don't think it is directly possible in JS for security reasons.But in here
they are claiming that it is possible and is useful for when you want something special to happen when DevTools is open. Like pausing canvas, adding style debug info, etc.
But As #James Hill tell in this, I also thinks even if a browser chose to make this information accessible to the client, it would not be a standard implementation (supported across multiple browsers).
Also can also try this one also here.
It's not possible in any official cross browser way, but if the occasional false positive is acceptable, you can check for a window.onresize event. Users resizing their windows after loading a page is somewhat uncommon. It's even more effective if you expect users will be frequently opening the console, meaning less false positives as a percentage.
window.onresize = function(){
if ((window.outerHeight - window.innerHeight) > 100) {
// console was opened (or screen was resized)
}
}
Credit to https://stackoverflow.com/a/7809413/3774582. Although that question is chrome specific, the concept applies here.
To expand on this, if you need a very low tolerance on false positives, most window resizes will trigger this event dozens of times because it is usually done as a drag action, while opening the console will only trigger this once. If you can detect this, the approach will become even more accurate.
Note: This will fail to detect if the console is already open when the user visits the page, or if the user opens the console in a new window.
(function() {
'use strict';
const el = new Image();
let consoleIsOpen = false;
let consoleOpened = false;
Object.defineProperty(el, 'id', {
get: () => {
consoleIsOpen = true;
}
});
const verify = () => {
console.dir(el);
if (consoleIsOpen === false && consoleOpened === true) {
// console closed
window.dispatchEvent(new Event('devtools-opened'));
consoleOpened = false;
} else if (consoleIsOpen === true && consoleOpened === false) {
// console opened
window.dispatchEvent(new Event('devtools-closed'));
consoleOpened = true;
}
consoleIsOpen = false;
setTimeout(verify, 1000);
}
verify();
})();
window.addEventListener('devtools-opened', ()=>{console.log('opened')});
window.addEventListener('devtools-closed', ()=>{console.log('closed')});
Here is a code that worked for me.
This solution works like a charm
https://github.com/sindresorhus/devtools-detect
if you are not using modules - disable lines
// if (typeof module !== 'undefined' && module.exports) {
// module.exports = devtools;
// } else {
window.devtools = devtools;
// }
and result is then here
window.devtools.isOpen
I for my project use the blur event.
function yourFunction() {}
window.addEventListener('blur',(e)=>{e.preventDefault(); yourFunction()})
This will execute yourFunction when the window loses focus.
For instance when someone opens the DevTools.
Okay seems like it also fires when you try to access a different window... so maybe not the best solution.
Maybe pair it with looking at the width of the browser.
If it chainged you can be pretty sure about it I think

In a Firefox restartless add-on, how do I run code when a new window opens (listen for window open)?

I am starting to build a restartless Firefox add-on and I am having trouble setting up the bootstrap.js. Everyone seems to agree that the core of a bootstrap.js is pretty much boilerplate code, along these lines:
const Cc = Components.classes;
const Ci = Components.interfaces;
function startup() {
let wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
// then can control what happens with domWindow.document
}
}
function shutdown() {}
function install() {}
function uninstall() {}
This code works and I can control things in the existing windows. For example, domWindow.alert("text") successfully creates a standard alert saying "text" on every window that is currently open.
However, I can't find any code that will allow me to do things in new windows; i.e. those created after the script runs. What is the correct way to handle the creation of new windows and gain control over them, to the point where I could get another "text" alert from one when it is created?
Edit: Using the nsWindowMediator class and the code sample from MDN, I now have this:
var windowListener = {
onOpenWindow: function (aWindow) {
try {
let domWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
domWindow.addEventListener("load", function () {
domWindow.removeEventListener("load", arguments.callee, false);
//window has now loaded now do stuff to it
domWindow.alert("text");
}, false);
} catch (err) {
Services.prompt.alert(null, "Error", err);
}
},
onCloseWindow: function (aWindow) {},
onWindowTitleChange: function (aWindow, aTitle) {}
};
function startup(aData, aReason) {
// Load into any existing windows
try {
let wm = Cc["#mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
let windows = wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements()) {
let domWindow = windows.getNext().QueryInterface(Ci.nsIDOMWindow);
loadIntoWindow(domWindow);
}
} catch (err) {
Services.prompt.alert(null, "Error", err);
}
Services.wm.addListener(windowListener);
}
However, there is still no output from the onOpenWindow call - the "text" alert does not appear, nor does the error alert in the catch block. I can confirm that onOpenWindow is actually being entered; if I put a Services.prompt.alert() at the beginning of onOpenWindow, I get the alert when I create a new window. Unfortunately, I get an infinite loop of alerts and I have no idea why.
However, I can't find any code that will allow me to do things in new windows; i.e. those created after the script runs. What is the correct way to handle the creation of new windows and gain control over them, to the point where I could get another "text" alert from one when it is created?
The correct way to act on each window when it opens is to use addListener() from nsIWindowMediator. The example code below does this. The nsIWindowMediator is included in Services.jsm and is accessed through Services.wm.addListener(WindowListener). In order to use a window listener, you have to pass it an nsIWindowMediatorListener (ref2) object. An nsIWindowMediatorListener contains three keys: onOpenWindow, onCloseWindow, and onWindowTitleChange. Each should be defined as a function which will be called when the appropriate event occurs.
The MDN document How to convert an overlay extension to restartless in "Step 9: bootstrap.js" contains an example of a basic bootstrap.js which will run the code in the function loadIntoWindow(window) for each currently open browser window and any browser window which opens in the future. I have used code modified from this in a couple of different add-ons. The example is substantially similar to the code you are already using. The example is (slightly modified):
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
function startup(data,reason) {
// Load this add-ons module(s):
Components.utils.import("chrome://myAddon/content/myModule.jsm");
// Do whatever initial startup stuff is needed for this add-on.
// Code is in module just loaded.
myModule.startup();
// Make changes to the Firefox UI to hook in this add-on
forEachOpenWindow(loadIntoWindow);
// Listen for any windows that open in the future
Services.wm.addListener(WindowListener);
}
function shutdown(data,reason) {
if (reason == APP_SHUTDOWN)
return;
// Unload the UI from each window
forEachOpenWindow(unloadFromWindow);
// Stop listening for new windows to open.
Services.wm.removeListener(WindowListener);
// Do whatever shutdown stuff you need to do on add-on disable
myModule.shutdown();
// Unload the module(s) loaded specific to this extension.
// Use the same URL for your module(s) as when loaded:
Components.utils.unload("chrome://myAddon/content/myModule.jsm");
// HACK WARNING: The Addon Manager does not properly clear all add-on related caches
// on update. In order to fully update images and locales, their
// caches need clearing here.
Services.obs.notifyObservers(null, "chrome-flush-caches", null);
}
function install(data,reason) { }
function uninstall(data,reason) { }
function loadIntoWindow(window) {
/* call/move your UI construction function here */
}
function unloadFromWindow(window) {
/* call/move your UI tear down function here */
}
function forEachOpenWindow(todo) {
// Apply a function to all open browser windows
var windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements())
todo(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
}
var WindowListener = {
onOpenWindow: function(xulWindow) {
var window = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
function onWindowLoad() {
window.removeEventListener("load",onWindowLoad);
// Only add UI changes if this is a browser window
if (window.document.documentElement.getAttribute("windowtype")
== "navigator:browser")
loadIntoWindow(window);
}
window.addEventListener("load",onWindowLoad);
},
onCloseWindow: function(xulWindow) { },
onWindowTitleChange: function(xulWindow, newTitle) { }
};
While there is quite a bit more that your might want to do in your bootstrap.js code, the above is organized reasonably well and keeps all of the code to load into the Firefox UI within loadIntoWindow(window) and unloading the UI within unloadFromWindow(window). However, it should be noted that some UI elements you should only be adding/removing once (e.g. australis widgets, like buttons) and other elements (e.g. direct changes to the Firefox DOM) have to be added once in each window.
Unfortunately, I get an infinite loop of alerts and I have no idea why.
One of the significant differences between this example and what you are currently using is the test for the type of window that has opened. This is done so that we are only acting on newly opened windows which are browser windows instead of all newly opened windows:
if (window.document.documentElement.getAttribute("windowtype") == "navigator:browser")
loadIntoWindow(window);
The problem you describe of getting an infinite loop of alert() popups is caused by not checking to make sure that you are only acting on browser windows. The alert() popup is a window. Thus, you are calling alert() for every alert() window you open which, of course, just opens another alert() window on which you call alert(). This is your infinite loop.
Additional references:
1. Working with windows in chrome code
However, I can't find any code that will allow me to do things in new windows
When working with XPCOM objects you generally want to study their interfaces, which are often found on MDN. In this case your starting point would be nsIWindowMediator, since that's the service you're using in line 5.
As you can see it has an addListener function, which takes a parameter implementing nsIWindowMediatorListener. There's a code-example right there on the page.
But let's assume for the moment there isn't a code example. You could search for the interface on MDN, but it isn't listed. The next step would be searching MXR for the .idl. idl = interface description language
Once you got the interface contract you can more or less just implement it in javascript, at least for listeners. Implementing your own xpcom services would be a little more complicated.
Searching the addon sdk can often provide some hints too. In this case they don't seem to be using .addListener, but the file hints at another interesting service, which in turn you can find on MDN: nsIWindowWatcher.
Basically, if you're writing restartless addons you're rummaging through the entrails of firefox and will have to do some detective work to find the exact components you need. If you want something more convenient I would recommend the addon sdk, which provides a more organized but also more restricted set of commonly used APIs

Instances Of Firefox Browser In Extension

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

IE7 window.open when .focus return null

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.

Categories