Skip to content

Commit 2fbf13a

Browse files
committed
initial commit
1 parent 1bcff40 commit 2fbf13a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+2754
-4
lines changed

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# IDEs
2+
.idea
3+
14
# Logs
25
logs
36
*.log

.npmignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
test
2+
.idea
3+
SampleApp
4+
.gitignore
5+
docs

AddressBar.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
'use strict';
2+
3+
import React from 'react-native';
4+
var {
5+
TextInput,
6+
View,
7+
} = React;
8+
9+
import BaseComponent from './BaseComponent'
10+
import Utils from './Utils'
11+
import styles from './styles'
12+
13+
const TEXT_INPUT_REF = 'urlInput';
14+
15+
class AddressBar extends BaseComponent {
16+
17+
constructor(props) {
18+
super(props);
19+
20+
this.inputText = '';
21+
22+
this.state = {
23+
url: this.props.url
24+
};
25+
26+
this._bind(
27+
'handleTextInputChange',
28+
'onSubmitEditing'
29+
);
30+
}
31+
32+
componentWillReceiveProps(nextProps) {
33+
this.setState({
34+
url: nextProps.url
35+
});
36+
}
37+
38+
handleTextInputChange(event) {
39+
const url = Utils.sanitizeUrl(event.nativeEvent.text);
40+
this.inputText = url;
41+
}
42+
43+
onSubmitEditing(event) {
44+
this.load();
45+
}
46+
47+
load() {
48+
const url = this.inputText;
49+
if (url === this.props.url) {
50+
this.props.onReload();
51+
} else {
52+
this.props.onLoad(url)
53+
}
54+
// dismiss keyboard
55+
this.refs[TEXT_INPUT_REF].blur();
56+
}
57+
58+
render() {
59+
return (
60+
<View style={[styles.addressBarRow]}>
61+
<TextInput
62+
ref={TEXT_INPUT_REF}
63+
autoCapitalize="none"
64+
defaultValue={this.state.url}
65+
onSubmitEditing={this.onSubmitEditing}
66+
onChange={this.handleTextInputChange}
67+
clearButtonMode="while-editing"
68+
style={[styles.addressBarTextInput, this.props.foregroundColor && {color:this.props.foregroundColor}]}
69+
/>
70+
</View>
71+
);
72+
}
73+
}
74+
75+
AddressBar.propTypes = {
76+
url: React.PropTypes.string,
77+
onLoad: React.PropTypes.func,
78+
onReload: React.PropTypes.func,
79+
foregroundColor: React.PropTypes.string
80+
};
81+
82+
AddressBar.defaultProps = {
83+
url: '',
84+
onLoad: (url)=>{},
85+
onReload: ()=>{}
86+
};
87+
88+
module.exports = AddressBar;
89+

BaseComponent.js

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
import React from 'react-native';
4+
5+
export default class BaseComponent extends React.Component {
6+
_bind(...methods) {
7+
methods.forEach( (method) => this[method] = this[method].bind(this) );
8+
}
9+
}

Button.js

+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
'use strict';
2+
3+
var React = require('react-native');
4+
var {
5+
View,
6+
TouchableOpacity,
7+
StyleSheet,
8+
PropTypes,
9+
ActivityIndicatorIOS,
10+
ProgressBarAndroid,
11+
TouchableNativeFeedback,
12+
Platform,
13+
Component
14+
} = React;
15+
16+
const IS_ANDROID = Platform.OS === 'android';
17+
18+
class Button extends Component {
19+
20+
constructor() {
21+
super();
22+
this.state = {}
23+
}
24+
25+
_renderChildAndroid() {
26+
27+
if (this.props.loading) {
28+
return (
29+
<ProgressBarAndroid
30+
style={[{height: 20}, styles.spinner]}
31+
styleAttr='Inverse'
32+
color={this.props.activityIndicatorColor || 'black'}
33+
/>
34+
);
35+
}
36+
37+
return this.props.children;
38+
}
39+
40+
_renderChildiOS() {
41+
if (this.props.loading) {
42+
return (
43+
<ActivityIndicatorIOS
44+
animating={true}
45+
size='small'
46+
style={styles.spinner}
47+
color={this.props.activityIndicatorColor || 'black'}
48+
/>
49+
);
50+
}
51+
return this.props.children;
52+
}
53+
54+
_renderChild() {
55+
if (IS_ANDROID) {
56+
return this._renderChildAndroid()
57+
}
58+
return this._renderChildiOS()
59+
}
60+
61+
render() {
62+
if (this.props.disabled === true || this.props.loading === true) {
63+
return (
64+
<View style={[styles.button, this.props.style, (this.props.disabledStyle || styles.opacity)]}>
65+
{this._renderChild()}
66+
</View>
67+
);
68+
} else {
69+
// Extract Touchable props
70+
var touchableProps = {
71+
onPress: this.props.onPress,
72+
onPressIn: this.props.onPressIn,
73+
onPressOut: this.props.onPressOut,
74+
onLongPress: this.props.onLongPress
75+
};
76+
if (IS_ANDROID) {
77+
touchableProps = Object.assign(touchableProps, {
78+
background: this.props.background || TouchableNativeFeedback.SelectableBackground()
79+
});
80+
return (
81+
<TouchableNativeFeedback {...touchableProps}>
82+
{this._renderChildAndroid()}
83+
</TouchableNativeFeedback>
84+
)
85+
} else {
86+
return (
87+
<TouchableOpacity {...touchableProps}
88+
style={[styles.button, this.props.style]}>
89+
{this._renderChildiOS()}
90+
</TouchableOpacity>
91+
);
92+
}
93+
}
94+
}
95+
}
96+
97+
Button.propTypes = {
98+
loading: PropTypes.bool,
99+
disabled: PropTypes.bool,
100+
onPress: PropTypes.func,
101+
onLongPress: PropTypes.func,
102+
onPressIn: PropTypes.func,
103+
onPressOut: PropTypes.func
104+
};
105+
106+
var styles = StyleSheet.create({
107+
button: {
108+
},
109+
textButton: {
110+
fontSize: 18,
111+
alignSelf: 'center'
112+
},
113+
spinner: {
114+
alignSelf: 'center'
115+
},
116+
opacity: {
117+
opacity: 0.5
118+
}
119+
});
120+
121+
module.exports = Button;

README.md

+49-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,50 @@
11
# react-native-webbrowser
2-
A cross-platform (iOS / Android), full-featured web browser module for React Native apps.
2+
A cross-platform (iOS / Android), full-featured in-app web browser component for React Native that is highly highly customizable. Currently you can hide the address-, status- and toolbar. Aditionally the foreground and background colors can be modified.
3+
4+
## Install
5+
6+
```sh
7+
npm i react-native-webbrowser --save
8+
```
9+
10+
## Usage
11+
12+
Here is an extensive overview of the component usage.
13+
14+
```jsx
15+
16+
class SampleApp extends Component {
17+
render() {
18+
return (
19+
<View style={{paddingTop:20, flex:1}}>
20+
21+
<Webbrowser
22+
url="https://your-url.com"
23+
hideHomeButton={false}
24+
hideToolbar={false}
25+
hideAddressBar={false}
26+
hideStatusBar={false}
27+
foregroundColor={'#efefef'}
28+
backgroundColor={'#333'}
29+
/>
30+
31+
</View>
32+
);
33+
}
34+
}
35+
```
36+
37+
## Props
38+
39+
* `url - string` required, web address
40+
* `hideAddressBar - bool` optional, hides the address bar / address input
41+
* `hideStatusBar - bool` optional, hides the status bar / site title
42+
* `hideToolbar - bool` optional, hides the toolbar (nav bar)
43+
* `hideHomeButton - bool` optional, hides just the home button from the toolbar
44+
* `foregroundColor - string` optional, sets the forground color of text and icon elements
45+
* `backgroundColor - string` optional, sets the background color
46+
47+
## Screenshot
48+
49+
![example](https://raw.githubusercontent.com/d-a-n/react-native-webbrowser/master/assets/images/screenshot.png)
50+
![example](https://raw.githubusercontent.com/d-a-n/react-native-webbrowser/master/assets/images/screenshot2.png)

SampleApp/.flowconfig

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
[ignore]
2+
3+
# We fork some components by platform.
4+
.*/*.web.js
5+
.*/*.android.js
6+
7+
# Some modules have their own node_modules with overlap
8+
.*/node_modules/node-haste/.*
9+
10+
# Ugh
11+
.*/node_modules/babel.*
12+
.*/node_modules/babylon.*
13+
.*/node_modules/invariant.*
14+
15+
# Ignore react and fbjs where there are overlaps, but don't ignore
16+
# anything that react-native relies on
17+
.*/node_modules/fbjs/lib/Map.js
18+
.*/node_modules/fbjs/lib/Promise.js
19+
.*/node_modules/fbjs/lib/fetch.js
20+
.*/node_modules/fbjs/lib/ExecutionEnvironment.js
21+
.*/node_modules/fbjs/lib/isEmpty.js
22+
.*/node_modules/fbjs/lib/crc32.js
23+
.*/node_modules/fbjs/lib/ErrorUtils.js
24+
25+
# Flow has a built-in definition for the 'react' module which we prefer to use
26+
# over the currently-untyped source
27+
.*/node_modules/react/react.js
28+
.*/node_modules/react/lib/React.js
29+
.*/node_modules/react/lib/ReactDOM.js
30+
31+
# Ignore commoner tests
32+
.*/node_modules/commoner/test/.*
33+
34+
# See https://github.com/facebook/flow/issues/442
35+
.*/react-tools/node_modules/commoner/lib/reader.js
36+
37+
# Ignore jest
38+
.*/node_modules/jest-cli/.*
39+
40+
# Ignore Website
41+
.*/website/.*
42+
43+
[include]
44+
45+
[libs]
46+
node_modules/react-native/Libraries/react-native/react-native-interface.js
47+
48+
[options]
49+
module.system=haste
50+
51+
munge_underscores=true
52+
53+
module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub'
54+
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\)$' -> 'RelativeImageStub'
55+
56+
suppress_type=$FlowIssue
57+
suppress_type=$FlowFixMe
58+
suppress_type=$FixMe
59+
60+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)
61+
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(2[0-1]\\|1[0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+
62+
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
63+
64+
[version]
65+
0.21.0

SampleApp/.gitignore

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# OSX
2+
#
3+
.DS_Store
4+
5+
# Xcode
6+
#
7+
build/
8+
*.pbxuser
9+
!default.pbxuser
10+
*.mode1v3
11+
!default.mode1v3
12+
*.mode2v3
13+
!default.mode2v3
14+
*.perspectivev3
15+
!default.perspectivev3
16+
xcuserdata
17+
*.xccheckout
18+
*.moved-aside
19+
DerivedData
20+
*.hmap
21+
*.ipa
22+
*.xcuserstate
23+
project.xcworkspace
24+
25+
# Android/IJ
26+
#
27+
.idea
28+
.gradle
29+
local.properties
30+
31+
# node.js
32+
#
33+
node_modules/
34+
npm-debug.log

SampleApp/.watchmanconfig

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

0 commit comments

Comments
 (0)