--- /dev/null
+// Copyright 2013 The Obvious Corporation.
+
+/**
+ * @fileoverview Helpers made available via require('phantomjs') once package is
+ * installed.
+ */
+
+var fs = require('fs')
+var path = require('path')
+var spawn = require('child_process').spawn
+var Promise = require('es6-promise').Promise
+
+
+/**
+ * Where the phantom binary can be found.
+ * @type {string}
+ */
+try {
+ var location = require('./location')
+ exports.path = path.resolve(__dirname, location.location)
+ exports.platform = location.platform
+ exports.arch = location.arch
+} catch(e) {
+ // Must be running inside install script.
+ exports.path = null
+}
+
+
+/**
+ * The version of phantomjs installed by this package.
+ * @type {number}
+ */
+exports.version = '2.1.1'
+
+
+/**
+ * Returns a clean path that helps avoid `which` finding bin files installed
+ * by NPM for this repo.
+ * @param {string} path
+ * @return {string}
+ */
+exports.cleanPath = function (path) {
+ return path
+ .replace(/:[^:]*node_modules[^:]*/g, '')
+ .replace(/(^|:)\.\/bin(\:|$)/g, ':')
+ .replace(/^:+/, '')
+ .replace(/:+$/, '')
+}
+
+
+// Make sure the binary is executable. For some reason doing this inside
+// install does not work correctly, likely due to some NPM step.
+if (exports.path) {
+ try {
+ // avoid touching the binary if it's already got the correct permissions
+ var st = fs.statSync(exports.path)
+ var mode = st.mode | parseInt('0555', 8)
+ if (mode !== st.mode) {
+ fs.chmodSync(exports.path, mode)
+ }
+ } catch (e) {
+ // Just ignore error if we don't have permission.
+ // We did our best. Likely because phantomjs was already installed.
+ }
+}
+
+/**
+ * Executes a script or just runs PhantomJS
+ */
+exports.exec = function () {
+ var args = Array.prototype.slice.call(arguments)
+ return spawn(exports.path, args)
+}
+
+/**
+ * Runs PhantomJS with provided options
+ * @example
+ * // handy with WebDriver
+ * phantomjs.run('--webdriver=4444').then(program => {
+ * // do something
+ * program.kill()
+ * })
+ * @returns {Promise} the process of PhantomJS
+ */
+exports.run = function () {
+ var args = arguments
+ return new Promise(function (resolve, reject) {
+ try {
+ var program = exports.exec.apply(null, args)
+ var isFirst = true
+ var stderr = ''
+ program.stdout.on('data', function () {
+ // This detects PhantomJS instance get ready.
+ if (!isFirst) return
+ isFirst = false
+ resolve(program)
+ })
+ program.stderr.on('data', function (data) {
+ stderr = stderr + data.toString('utf8')
+ })
+ program.on('error', function (err) {
+ if (!isFirst) return
+ isFirst = false
+ reject(err)
+ })
+ program.on('exit', function (code) {
+ if (!isFirst) return
+ isFirst = false
+ if (code == 0) {
+ // PhantomJS doesn't use exit codes correctly :(
+ if (stderr.indexOf('Error:') == 0) {
+ reject(new Error(stderr))
+ } else {
+ resolve(program)
+ }
+ } else {
+ reject(new Error('Exit code: ' + code))
+ }
+ })
+ } catch (err) {
+ reject(err)
+ }
+ })
+}