1 | var headless = require('headless');
|
2 | var fs = require('fs');
|
3 | var path = require('path');
|
4 | var spawn = require('child_process').spawn;
|
5 |
|
6 | var argue = {};
|
7 | argue.firefox = function (br, uri, opts, cb) {
|
8 | var prefs = '';
|
9 | opts.options = opts.options || [];
|
10 | if (opts.proxy) {
|
11 | var m = /^(?:http:\/\/)?([^:\/]+)(?::(\d+))?/.exec(opts.proxy);
|
12 | var host = JSON.stringify(m[1]);
|
13 | var port = m[2] || 80;
|
14 | prefs += [
|
15 | '"network.proxy.http", ' + host,
|
16 | '"network.proxy.http_port", ' + port,
|
17 | '"network.proxy.type", 1',
|
18 | '"browser.cache.disk.capacity", 0',
|
19 | '"browser.cache.disk.smart_size.enabled", false',
|
20 | '"browser.cache.disk.smart_size.first_run", false',
|
21 | '"browser.sessionstore.resume_from_crash", false',
|
22 | '"browser.startup.page", 0',
|
23 | '"network.proxy.no_proxies_on", '
|
24 | + JSON.stringify(opts.noProxy || '')
|
25 | ,
|
26 | ].map(function (x) { return 'user_pref(' + x + ');\n' }).join('');
|
27 | }
|
28 |
|
29 | prefs += 'user_pref("browser.shell.checkDefaultBrowser", false);\n';
|
30 |
|
31 | var file = path.join(path.dirname(br.profile.file), 'user.js');
|
32 | fs.writeFile(file, prefs, function (err) {
|
33 | if (err) cb(err)
|
34 | else cb(null, opts.options.concat([
|
35 | '--no-remote',
|
36 | '-P', br.profile.name,
|
37 | uri,
|
38 | ]))
|
39 | });
|
40 | };
|
41 |
|
42 | argue.ie = function(br, uri, opts, cb) {
|
43 | cb(null, [uri]);
|
44 | };
|
45 |
|
46 | argue.safari = function(br, uri, opts, cb) {
|
47 | cb(null, [uri]);
|
48 | };
|
49 |
|
50 | argue.chrome = function (br, uri, opts, cb) {
|
51 | opts.options = opts.options || [];
|
52 | cb(null, opts.options.concat([
|
53 | opts.proxy ? '--proxy-server=' + opts.proxy : null,
|
54 | br.profile ? '--user-data-dir=' + br.profile : null,
|
55 | '--disable-restore-session-state',
|
56 | '--no-default-browser-check',
|
57 | '--start-maximized',
|
58 | '--disable-default-apps',
|
59 | '--disable-sync',
|
60 | '--enable-fixed-layout',
|
61 | '--no-first-run',
|
62 | '--noerrdialogs ',
|
63 | uri,
|
64 | ]).filter(Boolean));
|
65 | };
|
66 |
|
67 | argue.phantom = function (br, uri, opts, cb) {
|
68 |
|
69 | opts.options = opts.options || [];
|
70 | var file = path.join(br.profile, 'phantom.js');
|
71 | var src = '(new WebPage).open('
|
72 | + JSON.stringify(uri)
|
73 | + ',function(){})'
|
74 | ;
|
75 | fs.writeFile(file, src, function (err) {
|
76 | if (err) cb(err)
|
77 | else cb(null, opts.options.concat([
|
78 | opts.proxy ?
|
79 | '--proxy=' + opts.proxy.replace(/^http:\/\//, '')
|
80 | : null
|
81 | ,
|
82 | file
|
83 | ]).filter(Boolean))
|
84 | });
|
85 | };
|
86 |
|
87 | module.exports = function (config, name, version) {
|
88 | var m = selectMatch(config, name, version);
|
89 | if (!m) return;
|
90 | return function (uri, opts, cb) {
|
91 | if (opts.headless && !m.headless) {
|
92 | headless(function (err, proc, display) {
|
93 | run({ DISPLAY : ':' + display });
|
94 | });
|
95 | }
|
96 | else run({})
|
97 |
|
98 | function run (env_) {
|
99 | var env = {},
|
100 | cwd = process.cwd();
|
101 |
|
102 | Object.keys(process.env).forEach(function (key) {
|
103 | env[key] = process.env[key];
|
104 | });
|
105 | Object.keys(env_).forEach(function (key) {
|
106 | env[key] = env_[key];
|
107 | });
|
108 |
|
109 | argue[m.type](m, uri, opts, function (err, args) {
|
110 | if (err) return cb(err);
|
111 | if (opts.noProxy && env.no_proxy === undefined) {
|
112 | env.no_proxy = opts.noProxy;
|
113 | }
|
114 | if (opts.proxy && env.http_proxy === undefined) {
|
115 | env.http_proxy = opts.proxy;
|
116 | }
|
117 | if (opts.proxy && env.HTTP_PROXY === undefined) {
|
118 | env.HTTP_PROXY = opts.proxy;
|
119 | }
|
120 | switch (process.platform) {
|
121 | case 'win32':
|
122 | m.command = m.command.replace(/"/g, '');
|
123 | cwd = require('path').dirname(m.command);
|
124 | break;
|
125 | case 'darwin':
|
126 | if (m.name !== 'firefox' && m.name !== 'phantom') {
|
127 | |
128 |
|
129 |
|
130 |
|
131 | args.unshift('--args');
|
132 | args.unshift(args.pop());
|
133 | args.unshift(m.command);
|
134 | args.unshift('-a');
|
135 | args.unshift('--fresh');
|
136 | args.unshift('--new');
|
137 | args.unshift('--wait-apps');
|
138 | m.command = 'open';
|
139 | }
|
140 | break;
|
141 | }
|
142 | cb(null, spawn(m.command, args, { env : env, cwd: cwd }));
|
143 |
|
144 | });
|
145 | }
|
146 | };
|
147 | };
|
148 |
|
149 | function selectMatch (config, name, version) {
|
150 | var order = (config.preference || []).concat(Object.keys(config.browsers));
|
151 | for (var i = 0; i < order.length; i++) {
|
152 | var bs = config.browsers[order[i]];
|
153 | var matching = bs
|
154 | .filter(function (b) {
|
155 | return b.name === name
|
156 | && matches(b.version, version)
|
157 | ;
|
158 | })
|
159 | .sort(function (a, b) {
|
160 | return b.version - a.version;
|
161 | })
|
162 | ;
|
163 | if (matching.length) return matching[0];
|
164 | }
|
165 | }
|
166 |
|
167 | function matches (version, pattern) {
|
168 | if (pattern === undefined || pattern === '*') return true;
|
169 |
|
170 |
|
171 | var vs = version.split('.');
|
172 | var ps = pattern.split('.');
|
173 | for (var i = 0; i < ps.length; i++) {
|
174 | if (ps[i] === 'x' || ps[i] === '*') continue;
|
175 | if (ps[i] !== vs[i]) return false;
|
176 | }
|
177 | return true;
|
178 | }
|