Skip to content

Commit 750e962

Browse files
committed
Add file.
0 parents  commit 750e962

File tree

5 files changed

+243
-0
lines changed

5 files changed

+243
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
open-browsers
2+
---
3+
4+
Attempts to open the browser with a given URL.
5+
On Mac OS X, attempts to reuse an existing Chrome tab via AppleScript.
6+
Otherwise, falls back to [opn](https://github.com/sindresorhus/opn) behavior.
7+
8+
`open-browsers` form [react-dev-utils](https://github.com/facebook/create-react-app/blob/next/packages/react-dev-utils/openBrowser.js)
9+
10+
11+
> openBrowsers(url: string): boolean
12+
13+
```js
14+
var path = require('path');
15+
var openBrowsers = require('open-browsers');
16+
17+
if (openBrowsers('http://localhost:3000')) {
18+
console.log('The browser tab has been opened!');
19+
}
20+
```

index.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
'use strict';
9+
10+
var chalk = require('colors-cli');
11+
var execSync = require('child_process').execSync;
12+
var spawn = require('cross-spawn');
13+
var opn = require('opn');
14+
15+
// https://github.com/sindresorhus/opn#app
16+
var OSX_CHROME = 'google chrome';
17+
18+
const Actions = Object.freeze({
19+
NONE: 0,
20+
BROWSER: 1,
21+
SCRIPT: 2,
22+
});
23+
24+
function getBrowserEnv() {
25+
// Attempt to honor this environment variable.
26+
// It is specific to the operating system.
27+
// See https://github.com/sindresorhus/opn#app for documentation.
28+
const value = process.env.BROWSER;
29+
let action;
30+
if (!value) {
31+
// Default.
32+
action = Actions.BROWSER;
33+
} else if (value.toLowerCase().endsWith('.js')) {
34+
action = Actions.SCRIPT;
35+
} else if (value.toLowerCase() === 'none') {
36+
action = Actions.NONE;
37+
} else {
38+
action = Actions.BROWSER;
39+
}
40+
return { action, value };
41+
}
42+
43+
function executeNodeScript(scriptPath, url) {
44+
const extraArgs = process.argv.slice(2);
45+
const child = spawn('node', [scriptPath, ...extraArgs, url], {
46+
stdio: 'inherit',
47+
});
48+
child.on('close', code => {
49+
if (code !== 0) {
50+
console.log();
51+
console.log(
52+
chalk.red(
53+
'The script specified as BROWSER environment variable failed.'
54+
)
55+
);
56+
console.log(chalk.cyan(scriptPath) + ' exited with code ' + code + '.');
57+
console.log();
58+
return;
59+
}
60+
});
61+
return true;
62+
}
63+
64+
function startBrowserProcess(browser, url) {
65+
// If we're on OS X, the user hasn't specifically
66+
// requested a different browser, we can try opening
67+
// Chrome with AppleScript. This lets us reuse an
68+
// existing tab when possible instead of creating a new one.
69+
const shouldTryOpenChromeWithAppleScript =
70+
process.platform === 'darwin' &&
71+
(typeof browser !== 'string' || browser === OSX_CHROME);
72+
73+
if (shouldTryOpenChromeWithAppleScript) {
74+
try {
75+
// Try our best to reuse existing tab
76+
// on OS X Google Chrome with AppleScript
77+
execSync('ps cax | grep "Google Chrome"');
78+
execSync('osascript openChrome.applescript "' + encodeURI(url) + '"', {
79+
cwd: __dirname,
80+
stdio: 'ignore',
81+
});
82+
return true;
83+
} catch (err) {
84+
// Ignore errors.
85+
}
86+
}
87+
88+
// Another special case: on OS X, check if BROWSER has been set to "open".
89+
// In this case, instead of passing `open` to `opn` (which won't work),
90+
// just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
91+
// https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768
92+
if (process.platform === 'darwin' && browser === 'open') {
93+
browser = undefined;
94+
}
95+
96+
// Fallback to opn
97+
// (It will always open new tab)
98+
try {
99+
var options = { app: browser };
100+
opn(url, options).catch(() => { }); // Prevent `unhandledRejection` error.
101+
return true;
102+
} catch (err) {
103+
return false;
104+
}
105+
}
106+
107+
/**
108+
* Reads the BROWSER evironment variable and decides what to do with it. Returns
109+
* true if it opened a browser or ran a node.js script, otherwise false.
110+
*/
111+
function openBrowser(url) {
112+
const { action, value } = getBrowserEnv();
113+
switch (action) {
114+
case Actions.NONE:
115+
// Special case: BROWSER="none" will prevent opening completely.
116+
return false;
117+
case Actions.SCRIPT:
118+
return executeNodeScript(value, url);
119+
case Actions.BROWSER:
120+
return startBrowserProcess(value, url);
121+
default:
122+
throw new Error('Not implemented.');
123+
}
124+
}
125+
126+
module.exports = openBrowser;

package-lock.json

Lines changed: 79 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"name": "open-browsers",
3+
"version": "1.0.1",
4+
"description": "Attempts to open the browser with a given URL. On Mac OS X, attempts to reuse an existing Chrome tab via AppleScript.",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"keywords": [],
10+
"author": "",
11+
"license": "MIT",
12+
"dependencies": {
13+
"colors-cli": "^1.0.13",
14+
"cross-spawn": "^6.0.5",
15+
"opn": "^5.3.0"
16+
}
17+
}

0 commit comments

Comments
 (0)