├── .babelrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── package.json
├── src
├── inject-post-message.js
└── react-native-web-view.js
├── webpack.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [ "@babel/preset-env", "@babel/preset-react" ],
3 | "plugins": [
4 | "@babel/plugin-proposal-class-properties",
5 | "@babel/plugin-proposal-object-rest-spread"
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.git
2 | /node_modules
3 | /index.js
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /.git
2 | /node_modules
3 | /src
4 | /.babelrc
5 | /.gitignore
6 | /.npmignore
7 | /.travis.yml
8 | /webpack.config.js
9 | /yarn.lock
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js: 8.9.1
3 | branches:
4 | only: master
5 | cache: yarn
6 | install: yarn
7 | script:
8 | - yarn build
9 | - yarn test
10 | deploy:
11 | api_key:
12 | secure: lqYgY7yPzK3vc7+sK522cOxIEflfE89ikjzcEA4165iNNXgNG1NSNavSdj/6qnxHoCuiEC1I2zZjln3rPhrN0rJqvJcvjK/B5f90aLEJMXZCglmMW88QnsV6xhhqOrgATa/AV1fh9Q3Bhe/Fg+2kj61BSe5U3qJ3rPNhqxOG1SuJLBuWy3IP41kDsSEIYvG9yTWUq3b+tAN6rs2oqm8GhyTFv6tk5VpcQUo5pMyMfhLlfOOT9IlbnB5rO3n2EFAG+XXzgB3X49ZxuTpWdnqzJigAij3trV6m1jo2jSI7nKAYz8gQJqEBwI7S5b962twJAUcEpgP1/a//dfB0n6JLNz6SOyXrFcRcgjm0E8+RxbhZEYVtceo5bkD1+E+W3tDoM4yeTR49vxsj+6jeuy3JLbzzgAFTMk09x7ksqZUKnqjay91bloNu0N6ly8jUtV+uI4CucwalWjtACtyKGoB6FbJau3Y7rlnGaaHBDdUQjzVTBzQh6kuGaSHQ0/as6pDUrkpzjJ8HNtebMS9SST0aBK9lFn5lCNJwrE5N6DYjvItpuhgD4P8w454f69yygDpQpJjByiIqBvzcLavAnQdlceBJ6mKgurdcA3qb0whCjMlM+bECUjtHrym8ODMVFKMDyM4TJzRzOktoCKUNTky3xUfYb8NLI81qcQA/VvhuvwE=
13 | email: npmjs@charlesstover.com
14 | on:
15 | branch: master
16 | provider: npm
17 | skip_cleanup: true
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Charles Stover
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # React Native WebView [](https://twitter.com/intent/tweet?text=Trouble%20using%20postMessage%20in%20React%20Native%20on%20iOS?%20The%20rn-webvie%20package%20fixes%20this!&url=https://github.com/CharlesStover/react-native-web-view&via=CharlesStover&hashtags=react,reactjs,iosdev,javascript,mobileapp,mobileappdevelopment,mobiledev,webdev,webdeveloper,webdevelopment)
2 |
3 | An implementation of React Native's WebView that allows for `window.postMessage` on iOS devices.
4 |
5 | [](https://www.npmjs.com/package/rn-webview)
6 | [](https://www.npmjs.com/package/rn-webview)
7 | [](https://www.npmjs.com/package/rn-webview)
8 | [](https://www.npmjs.com/package/rn-webview)
9 | [](https://travis-ci.com/CharlesStover/react-native-web-view/)
10 |
11 | ## Install
12 |
13 | * `npm install rn-webview --save` or
14 | * `yarn add rn-webview`
15 |
16 | ## Use
17 |
18 | Instead of `import { WebView } from 'react-native'`, simply `import WebView from 'rn-webview'`.
19 | Then continue to use `` just like you would the React Native implementation.
20 |
21 | ## Sponsor 💗
22 |
23 | If you are a fan of this project, you may
24 | [become a sponsor](https://github.com/sponsors/CharlesStover)
25 | via GitHub's Sponsors Program.
26 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rn-webview",
3 | "version": "0.1.0",
4 | "author": "Charles Stover ",
5 | "bugs": {
6 | "url": "https://github.com/CharlesStover/react-native-web-view/issues"
7 | },
8 | "description": "An implementation of React Native's WebView that allows for window.postMessage on iOS devices.",
9 | "devDependencies": {
10 | "@babel/core": "^7.0.0-beta.56",
11 | "@babel/plugin-proposal-class-properties": "^7.0.0-beta.56",
12 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.56",
13 | "@babel/preset-env": "^7.0.0-beta.56",
14 | "@babel/preset-react": "^7.0.0-beta.56",
15 | "babel-core": "7.0.0-bridge.0",
16 | "babel-loader": "^8.0.0-beta.4",
17 | "react": "^16.3.1",
18 | "react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
19 | "webpack": "^4.16.4",
20 | "webpack-cli": "^3.1.0"
21 | },
22 | "homepage": "https://github.com/CharlesStover/react-native-web-view#readme",
23 | "keywords": [
24 | "react",
25 | "reactjs",
26 | "react-native",
27 | "reactnative"
28 | ],
29 | "license": "MIT",
30 | "main": "index.js",
31 | "peerDependencies": {
32 | "react": "^16.3.1",
33 | "react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz"
34 | },
35 | "repository": {
36 | "type": "git",
37 | "url": "git+https://github.com/CharlesStover/react-native-web-view.git"
38 | },
39 | "scripts": {
40 | "build": "webpack",
41 | "dev": "set NODE_ENV=development && webpack",
42 | "prepublishOnly": "npm run build",
43 | "test": "echo \"No test.\""
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/inject-post-message.js:
--------------------------------------------------------------------------------
1 | // Custom postMessage handler to inject into the Web View.
2 | export default `
3 | (function() {
4 | var EMPTY_STATE = Object.create(null);
5 | var escape = function(str) {
6 | return str.replace(/'/g, '\\\\\'');
7 | };
8 | var postMessage = window.postMessage;
9 | window.postMessage = function() {
10 | if (postMessage) {
11 | postMessage.apply(window, arguments);
12 | }
13 | history.pushState(
14 | EMPTY_STATE,
15 | document.title,
16 | location.href +
17 | '#window.postMessage(\\\'' +
18 | escape(arguments[0]) +
19 | '\\\')'
20 | );
21 | };
22 | })();
23 | `;
24 |
--------------------------------------------------------------------------------
/src/react-native-web-view.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { WebView } from 'react-native';
3 | import injectPostMessage from './inject-post-message';
4 |
5 | const unescape = str =>
6 | str.replace(/\\'/g, '\'');
7 |
8 | class WebViewPostMessage extends React.PureComponent {
9 |
10 | handleNavigationStateChange = e => {
11 |
12 | // If this navigation state contains a message to post, post it.
13 | const postMessage = e.url.match(/\#window\.postMessage\('(.+)'\)$/);
14 | if (postMessage) {
15 | if (
16 | e.loading &&
17 | this.props.onMessage
18 | ) {
19 | this.props.onMessage({
20 | nativeEvent: {
21 | data: unescape(postMessage[1])
22 | }
23 | });
24 | }
25 | return;
26 | }
27 |
28 | // If this navigation state has completed, listen for messages.
29 | if (
30 | !e.loading &&
31 | this.ref
32 | ) {
33 | this.ref.injectJavaScript(injectPostMessage);
34 | }
35 |
36 | // If a navigation state change event handler was passed, call it.
37 | if (this.props.onNavigationStateChange) {
38 | return this.props.onNavigationStateChange(e);
39 | }
40 | return;
41 | };
42 |
43 | // Grab the WebView ref for injecting JavaScript.
44 | handleRef = ref => {
45 | this.ref = ref;
46 |
47 | // If the caller also wants this ref, pass it along to them as well.
48 | if (this.props.forwardedRef) {
49 | this.props.forwardedRef(ref);
50 | }
51 | };
52 |
53 | render() {
54 |
55 | // Do not send onMessage to the React Native WebView, since it is not supported on iOS.
56 | const props = {...this.props};
57 | delete props.forwardedRef;
58 | delete props.onMessage;
59 |
60 | return (
61 |
66 | );
67 | }
68 | }
69 |
70 | // Export a component that allows refs to be forwarded, in case the user wants access to the WebView.
71 | export default React.forwardRef((props, ref) =>
72 |
76 | );
77 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 |
3 | const NODE_ENV =
4 | process.env.NODE_ENV ?
5 | process.env.NODE_ENV.trim() :
6 | 'production';
7 |
8 | module.exports = {
9 | entry: './src/react-native-web-view.js',
10 | externals: [
11 | {
12 | 'react': {
13 | amd: 'react',
14 | commonjs: 'react',
15 | commonjs2: 'react',
16 | root: 'React'
17 | }
18 | },
19 | 'react-native'
20 | ],
21 | mode: NODE_ENV,
22 | module: {
23 | rules: [
24 |
25 | // JavaScript
26 | {
27 | test: /\.js$/,
28 | use: {
29 | loader: 'babel-loader'
30 | }
31 | }
32 | ]
33 | },
34 | output: {
35 | filename: 'index.js',
36 | library: 'react-native-web-view',
37 | libraryTarget: 'umd',
38 | path: path.resolve(__dirname, '.'),
39 | umdNamedDefine: true
40 | },
41 | resolve: {
42 | alias: {
43 | 'react': path.resolve(__dirname, './node_modules/react'),
44 | 'react-native': path.resolve(__dirname, './node_modules/react-native')
45 | }
46 | },
47 | watch: NODE_ENV === 'development'
48 | };
49 |
--------------------------------------------------------------------------------