I have a javascript file that is normally used in a web browser using a script tag. It is a self-executing function that seems to put an object on the window (the window is passed in).
What would be the cleanest way to use it from node.js on the server?
Thanks,
Gareth
If all it does is add attributes to window, and you want to get those back out, you can create a global called window:
global.window = {};
require('theLibrary');
// now do something with global.window.theThingItAdded
However, if the library was written for the browser, it's possible that it still won't run because it wants to use the DOM. In that case, you might want to look into jsdom, which aims to give you a spec-compliant DOM inside Node.
(If you're using jsdom, I think that you would use it instead of the global.window bit above -- I think jsdom does that for you, but with a more full-featured window object. I haven't actually used jsdom, though, so I don't know for sure.)
Related
I'm writing some tests for my React-Native application (using JS) in a NodeJS environment. In one scenario, I need to attach to an already-running Windows application. In order to attach to this Application, I need to know the NativeWindowHandle value.
For example, if you open Inspect.exe on a window, you'll find the "NativeWindowHandle" hex value.
Is there anyway I can find this value programmatically?
What I've Tried:
I'm able to find the PID of the app using:
const exec = require('child_process').exec;
exec('tasklist', function (err, stdout) {
....
}}
However, I haven't been able to turn that into the window handle. Does anyone have any ideas here? Is this possible?
This can be reliably accomplished by writing a native (C++) node addon which calls the appropriate Windows API functions and passes the results back to JS land.
eg you might want to call FindWindowEx and Windows will find and return the HWND (native window handle) of the matching open window. Or use one of the enumeration functions if you need to do the search yourself.
I did a quick search of npm and it looks like there might be a few packages that have done this work already, but you'll need to evaluate them.
If none of the npm packages will work, you'll need to write it yourself. This isn't too hard if you have a little C++ knowledge, but alternatively you might be able to get away with using node-ffi, which lets you write everything in JS and marshals the native calls for you.
(Using ffi will be a little slower than writing the native module yourself, but for your purposes that doesn't really matter. Either native or ffi will be much faster than spawning child processes.)
With copy("text") in the developer tools console of Chrome and Firefox you can copy a "text" without an user interaction. Is this also possible if the website I've opened also has a function named copy? If yes, how?
If you refer to window overriding:
Unfortunately, once website overrides methods from window object, they are basically gone for good.
There are some workarounds, for instance you could use proxy interceptor like Charles, inject something like <script> window.copy_saved = window.copy; </script> on the very top of the <head> tag and then use copy_saved method with preserved original functionality.
If you refer to accessing functions defined in website's script tags:
It really depends on implementation, if the method is wrapped in structure accessible in window object, then yes, you can find a way to invoke the method. Methods however, can be stored in closure-like objects and thus being inaccessible by outside environment. It usually takes thorough reverse engineering to find a way into minified closures.
I have a rather large app made in Appcelerator Titanium, which I've not ported from the SDK version 3.2 because the Ti.Ui.Window's "url" property has been removed, which my application uses extensively. Unfortunately, I have not been able to find the new, correct way to do this. The info I'm finding out there does only point to the removal of the url property, or suggests that I should move to Alloy (which at the moment is not doable for me as it would require a complete rewrite of the app). Can anyone point me to an example of the right way this should be done?
If you're not using Alloy, then it's really a two step process. First you need to get the handle to the window. That is usually done with Ti.UI.createWindow (see http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI-method-createWindow). Now that you have a reference to the window, you simply open it. So,
var win = Ti.UI.createWindow({title: 'My first window'});
win.open();
Documentation on the window object is here. http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.Window
If you have windows defined in other js files. ie. myWindow.js, then you can use require to get the js window. Have the code in your window return a "Window" object, then open that.
ie. myWindow.js
var win = Ti.UI.createWindow({title: 'Window from another file'});
return win;
Then in your calling file, don't use url, require the window:
var myNewWindow = require('myWindow');
myNewWindow.open();
You can see information about calling require here: http://docs.appcelerator.com/platform/latest/#!/api/Global-method-require
Hope that helps.
Ray
I have a nodejs server (sockjs) not fully developed by me. At a certain point a function is called, but I could go back to where the function is defined (if it belongs to a certain module, official or custom)
There's a programmatical way to know where a certain function is defined?
You should use a debugger. This would allow you to put breakpoints, so you can locate where that specific function is called and go into.
There are plenty of IDEs, I am familiar with Webstorm (the debugger works well).
In my add-on, I'm using XUL to display dialog windows because I can customize their appearance to suit the add-on's general style (like a custom titlebar).
Using the migration guide, I'm able to do this easily. The thing is, I would like to call certain functions in the add-on's main module from the XUL dialog.
After a bit of searching I found the loader module, which seems to be able to do exactly what I want. But, I'm experiencing trouble in using it to access the main module.
First, I tried the obvious approach as mentioned in the documentation;
xul_dialog.js:
let {Loader} = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
let loader = Loader.Loader({
paths: {
'toolkit/': 'resource://gre/modules/commonjs/toolkit/',
'': 'resource:///modules/',
'./': 'resource://<my-addon-name>/root/'
}
});
let main = Loader.main(loader, './main');
I got an error that './main' was not found at resource://<my-addon-name>/root/. Figuring that I was using the incorrect paths, I experimented a bit until I could remove all path associated errors.
xul_dialog.js:
let {Loader} = Components.utils.import('resource://gre/modules/commonjs/toolkit/loader.js');
let loader = Loader.Loader({
paths: {
'toolkit/': 'resource://gre/modules/commonjs/toolkit/',
'': 'resource://gre/modules/commonjs/',
'./': 'resource://<my-addon-id>-at-jetpack/<my-addon-name>/lib/'
}
});
let main = Loader.main(loader, './main');
This time I got a rather confusing error at loader.js, line 279.
Components is not available in this context.
Functionality provided by Components may be available in an SDK
module: https://jetpack.mozillalabs.com/sdk/latest/docs/
However, if you still need to import Components, you may use the
`chrome` module's properties for shortcuts to Component properties:
Shortcuts:
Cc = Components.classes
Ci = Components.interfaces
Cu = Components.utils
CC = Components.Constructor
Example:
let { Cc, Ci } = require('chrome');
I get the same error when I use Loader.Require(loader, {id: './main'}) instead of Loader.main. I even tried passing Components as globals when instantiating the loader, but without much luck.
I'm fairly certain that I'm doing a lot of things wrong. I don't understand why I'm getting the error, even after spending quite a bit of time in loader.js. Plus, I also think that there would be a better alternative than having to use the add-on id for the path to main.js; hard-coding it like that doesn't seem right.
Any help would be really appreciated.
What you have to do is to find a specific instance of Loader, not create a new one.
At main.js
const { id, name, prefixURI } = require("#loader/options");
//pass these to the XUL dialog
At xul.js (or whatever is the name of the xul dialog script)
Components.utils.import("resource://gre/modules/addons/XPIProvider.jsm");
var extensionscope = XPIProvider.bootstrapScopes[id];
var mainjssandbox = extensionscope.loader.sandboxes[prefixURI + name + "/lib/main.js"];
Assuming there is a foo function at main.js, you can call it like
mainjssandbox.foo();
Of course don't expect things to work as if XUL and Add-on SDK actually blended into one thing.
If it is your XUL dialog that should interact with your add-on, then please don't use the Loader stuff and in particular do not go the XPIProvider.bootstrapScopes #paa suggested. While this might work (for now), it should be noted that it relies on tons of implementation details that are subject to change at any point making this solution extremely fragile.
Instead there are a couple of other options (not an exhaustive list):
If the SDK part opens the windows, you may use .openDialog which supports passing arguments to the created window, and these arguments can even be objects and functions. Also, you can have the window dispatch (custom) events, and which your SDK part can listen to by calling addEventListener on the window the .openDialog call returns.
If the window is created from somewhere else (e.g. from the AddonManager because of em:optionsURL) then the nsIObserverService is another way to communicate. The window could e.g. .notifyObservers on DOMContentLoaded containing a reference to itself. The SDK parts would just have to observe such notifications by addObserver.
Another way, a bit hacky but working, is the SDK part listening to new windows via nsIWindowWatcher.registerNotification and then injecting some API into e.g. browser.xul windows by XPCNativeWrapper.unwrap(subject.QueryInterface(Ci.nsIDOMWindow)).myAddonAPI = something.
Be sure to handle unloading or your add-on well - it is still restartless -, i.e. reverse any changes you've done and remove any observers and so on again.
If you want to interact with SDK addons not created by you, then the XPIProvider route might be the only feasible. But still, it might be worth contacting the add-on author first asking for the addition of some public API instead of hacking deep into the AddonManager and SDK loader internals.
PS:
Considering passing require or the global scope to your window via openDialog if you want to. Get the global scope by placing this into your main.js:
const globalScope = this;