nw-penetrate
Version:
Make the nwjs window penetrable. (Windows only)
172 lines (152 loc) • 4.62 kB
JavaScript
/**
* Module dependencies.
*/
var fs = require('fs'),
path = require('path'),
join = path.join,
dirname = path.dirname,
exists = fs.accessSync || path.accessSync,
defaults = {
arrow: process.env.NODE_BINDINGS_ARROW || ' → ',
compiled: process.env.NODE_BINDINGS_COMPILED_DIR || 'compiled',
platform: process.platform,
arch: process.arch,
version: process.versions.node,
bindings: 'bindings.node',
try: [
// node-gyp's linked version in the "build" dir
['module_root', 'build', 'bindings']
// node-waf and gyp_addon (a.k.a node-gyp)
,
['module_root', 'build', 'Debug', 'bindings'],
['module_root', 'build', 'Release', 'bindings']
// Debug files, for development (legacy behavior, remove for node v0.9)
,
['module_root', 'out', 'Debug', 'bindings'],
['module_root', 'Debug', 'bindings']
// Release files, but manually compiled (legacy behavior, remove for node v0.9)
,
['module_root', 'out', 'Release', 'bindings'],
['module_root', 'Release', 'bindings']
// Legacy from node-waf, node <= 0.4.x
,
['module_root', 'build', 'default', 'bindings']
// Production "Release" buildtype binary (meh...)
,
['module_root', 'compiled', 'version', 'platform', 'arch', 'bindings']
]
}
/**
* The main `bindings()` function loads the compiled bindings for a given module.
* It uses V8's Error API to determine the parent filename that this function is
* being invoked from, which is then used to find the root directory.
*/
function bindings(opts) {
// Argument surgery
if (typeof opts == 'string') {
opts = {
bindings: opts
}
} else if (!opts) {
opts = {}
}
opts.__proto__ = defaults
// Get the module root
if (!opts.module_root) {
opts.module_root = exports.getRoot(exports.getFileName())
}
// Ensure the given bindings name ends with .node
if (path.extname(opts.bindings) != '.node') {
opts.bindings += '.node'
}
var tries = [],
i = 0,
l = opts.try.length,
n, b, err
for (; i < l; i++) {
n = join.apply(null, opts.try[i].map(function(p) {
return opts[p] || p
}))
tries.push(n)
try {
b = opts.path ? require.resolve(n) : require(n)
if (!opts.path) {
b.path = n
}
return b
} catch (e) {
if (!/not find/i.test(e.message)) {
throw e
}
}
}
err = new Error('Could not locate the bindings file. Tried:\n' + tries.map(function(a) {
return opts.arrow + a
}).join('\n'))
err.tries = tries
throw err
}
module.exports = exports = bindings
/**
* Gets the filename of the JavaScript file that invokes this function.
* Used to help find the root directory of a module.
* Optionally accepts an filename argument to skip when searching for the invoking filename
*/
exports.getFileName = function getFileName(calling_file) {
var origPST = Error.prepareStackTrace,
origSTL = Error.stackTraceLimit,
dummy = {},
fileName
Error.stackTraceLimit = 10
Error.prepareStackTrace = function(e, st) {
for (var i = 0, l = st.length; i < l; i++) {
fileName = st[i].getFileName()
if (fileName !== __filename) {
if (calling_file) {
if (fileName !== calling_file) {
return
}
} else {
return
}
}
}
}
// run the 'prepareStackTrace' function above
Error.captureStackTrace(dummy)
dummy.stack
// cleanup
Error.prepareStackTrace = origPST
Error.stackTraceLimit = origSTL
return fileName
}
/**
* Gets the root directory of a module, given an arbitrary filename
* somewhere in the module tree. The "root directory" is the directory
* containing the `package.json` file.
*
* In: /home/nate/node-native-module/lib/index.js
* Out: /home/nate/node-native-module
*/
exports.getRoot = function getRoot(file) {
var dir = dirname(file),
prev
while (true) {
if (dir === '.') {
// Avoids an infinite loop in rare cases, like the REPL
dir = process.cwd()
}
try {
exists(join(dir, 'package.json'));
return dir;
} catch (e) {
}
if (prev === dir) {
// Got to the top
throw new Error('Could not find module root given file: "' + file + '". Do you have a `package.json` file? ')
}
// Try the parent dir next
prev = dir
dir = join(dir, '..')
}
}