react-native-htmlview
Advanced tools
Comparing version 0.2.0 to 0.4.0
105
HTMLView.js
@@ -1,6 +0,5 @@ | ||
var htmlparser = require('./vendor/htmlparser2') | ||
var entities = require('./vendor/entities') | ||
var React = require('react-native') | ||
var htmlToElement = require('./htmlToElement') | ||
var { | ||
LinkingIOS, | ||
Linking, | ||
StyleSheet, | ||
@@ -10,62 +9,19 @@ Text, | ||
var LINE_BREAK = '\n' | ||
var PARAGRAPH_BREAK = '\n\n' | ||
var BULLET = ' \u2022 ' | ||
function htmlToElement(rawHtml, opts, done) { | ||
function domToElement(dom, parent) { | ||
if (!dom) return null | ||
var HTMLView = React.createClass({ | ||
propTypes: { | ||
value: React.PropTypes.string, | ||
stylesheet: React.PropTypes.object, | ||
onLinkPress: React.PropTypes.func, | ||
onError: React.PropTypes.func, | ||
renderNode: React.PropTypes.func, | ||
}, | ||
return dom.map((node, index, list) => { | ||
if (opts.customRenderer) { | ||
var rendered = opts.customRenderer(node, index, list) | ||
if (rendered || rendered === null) return rendered | ||
} | ||
if (node.type == 'text') { | ||
return ( | ||
<Text key={index} style={parent ? opts.styles[parent.name] : null}> | ||
{entities.decodeHTML(node.data)} | ||
</Text> | ||
) | ||
} | ||
if (node.type == 'tag') { | ||
var linkPressHandler = null | ||
if (node.name == 'a' && node.attribs && node.attribs.href) { | ||
linkPressHandler = () => opts.linkHandler(entities.decodeHTML(node.attribs.href)) | ||
} | ||
return ( | ||
<Text key={index} onPress={linkPressHandler}> | ||
{node.name == 'pre' ? LINE_BREAK : null} | ||
{node.name == 'li' ? BULLET : null} | ||
{domToElement(node.children, node)} | ||
{node.name == 'br' ? LINE_BREAK : null} | ||
{node.name == 'li' ? LINE_BREAK : null} | ||
{node.name == 'p' && index < list.length-1 ? PARAGRAPH_BREAK : null} | ||
</Text> | ||
) | ||
} | ||
}) | ||
} | ||
var handler = new htmlparser.DomHandler(function (err, dom) { | ||
if (err) done(err) | ||
done(null, domToElement(dom)) | ||
}) | ||
var parser = new htmlparser.Parser(handler) | ||
parser.write(rawHtml) | ||
parser.done() | ||
} | ||
var HTMLView = React.createClass({ | ||
mixins: [ | ||
React.addons.PureRenderMixin, | ||
], | ||
getDefaultProps() { | ||
return { | ||
onLinkPress: LinkingIOS.openURL, | ||
onLinkPress: Linking.openURL, | ||
onError: console.error.bind(console), | ||
} | ||
}, | ||
getInitialState() { | ||
@@ -76,13 +32,21 @@ return { | ||
}, | ||
componentWillReceiveProps() { | ||
if (this.state.element) return | ||
this.startHtmlRender() | ||
componentWillReceiveProps(nextProps) { | ||
if (this.props.value !== nextProps.value) { | ||
this.startHtmlRender(nextProps.value) | ||
} | ||
}, | ||
componentDidMount() { | ||
this.startHtmlRender() | ||
this.mounted = true | ||
this.startHtmlRender(this.props.value) | ||
}, | ||
startHtmlRender() { | ||
if (!this.props.value) return | ||
if (this.renderingHtml) return | ||
componentWillUnmount() { | ||
this.mounted = false | ||
}, | ||
startHtmlRender(value) { | ||
if (!value) return this.setState({element: null}) | ||
var opts = { | ||
@@ -94,11 +58,12 @@ linkHandler: this.props.onLinkPress, | ||
this.renderingHtml = true | ||
htmlToElement(this.props.value, opts, (err, element) => { | ||
this.renderingHtml = false | ||
htmlToElement(value, opts, (err, element) => { | ||
if (err) return this.props.onError(err) | ||
if (err) return (this.props.onError || console.error)(err) | ||
if (!this.mounted) return | ||
if (this.isMounted()) this.setState({element}) | ||
// don't update rendered element if value has subsequently changed | ||
if (this.props.value === value) this.setState({element}) | ||
}) | ||
}, | ||
render() { | ||
@@ -109,3 +74,3 @@ if (this.state.element) { | ||
return <Text /> | ||
} | ||
}, | ||
}) | ||
@@ -112,0 +77,0 @@ |
@@ -1,1 +0,1 @@ | ||
module.exports = require('./HTMLView') | ||
module.exports = require('./HTMLView') |
{ | ||
"name": "react-native-htmlview", | ||
"version": "0.2.0", | ||
"version": "0.4.0", | ||
"description": "A component which renders HTML content as native views", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"lint": "eslint .", | ||
"jest": "jest", | ||
"test": "npm run lint && npm run jest" | ||
}, | ||
"jest": { | ||
"setupEnvScriptFile": "<rootDir>/test/support/setupTestFramework.js", | ||
"unmockedModulePathPatterns": [ | ||
"react", | ||
"react-addons-test-utils", | ||
"promise", | ||
"source-map" | ||
], | ||
"preprocessorIgnorePatterns": [ | ||
"/node_modules/" | ||
] | ||
}, | ||
"devDependencies": { | ||
"babel-eslint": "6.0.2", | ||
"babel-jest": "^10.0.2", | ||
"babel-preset-es2015": "^6.6.0", | ||
"babel-preset-react": "^6.5.0", | ||
"eslint": "2.7.0", | ||
"eslint-plugin-react": "4.3.0", | ||
"jest-cli": "^0.10.0", | ||
"react": "^0.14.5", | ||
"react-addons-test-utils": "^0.14.5", | ||
"react-native": "^0.23.1" | ||
}, | ||
"author": "James Friend <james@jsdf.co> (http://jsdf.co/)", | ||
@@ -20,7 +46,2 @@ "license": "ISC", | ||
], | ||
"files": [ | ||
"index.js", | ||
"HTMLView.js", | ||
"vendor/" | ||
], | ||
"homepage": "https://github.com/jsdf/react-native-htmlview", | ||
@@ -27,0 +48,0 @@ "bugs": "https://github.com/jsdf/react-native-htmlview/issues", |
@@ -28,9 +28,9 @@ # React Native HTMLView | ||
var ContentView = React.createClass({ | ||
var App = React.createClass({ | ||
render() { | ||
var htmlContent = '<p><a href="http://jsdf.co">♥ nice job!</a></p>' | ||
return ( | ||
var htmlContent = '<p><a href="">♥ nice job!</a></p>' | ||
<HTMLView | ||
value={htmlContent} | ||
onLinkPress={(url) => console.log('navigating to: ', url)} | ||
stylesheet={styles} | ||
@@ -50,2 +50,20 @@ /> | ||
When a link is clicked, by default `React.Linking.openURL` is called with the | ||
link url. You can customise what happens when a link is clicked with `onLinkPress`: | ||
```js | ||
var React = require('react-native') | ||
var ContentView = React.createClass({ | ||
render() { | ||
return ( | ||
<HTMLView | ||
value={this.props.html} | ||
onLinkPress={(url) => console.log('clicked link: ', url)} | ||
/> | ||
) | ||
} | ||
}) | ||
``` | ||
### screenshot | ||
@@ -61,4 +79,5 @@ | ||
 | ||
I just wrote this... use at your own risk. Not API stable. | ||
### changelog | ||
- 0.4.0 - re-renders properly when html content changes |
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
309860
14
7129
1
81
10