🚨 Active Supply Chain Attack:node-ipc Package Compromised.Learn More
Socket
Book a DemoSign in
Socket

@chainplatform/react-native-htmlview

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@chainplatform/react-native-htmlview - npm Package Compare versions

Comparing version
0.17.1
to
0.17.2
+47
-44
AutoSizedImage.js

@@ -1,55 +0,58 @@

import React, { PureComponent } from 'react';
import { Image, Dimensions } from 'react-native';
import React, {PureComponent} from 'react';
import {Image, Dimensions} from 'react-native';
const { width } = Dimensions.get('window');
const {width} = Dimensions.get('window');
const baseStyle = {
backgroundColor: 'transparent',
backgroundColor: 'transparent',
};
export default class AutoSizedImage extends PureComponent {
constructor(props) {
super(props);
this.state = {
// set width 1 is for preventing the warning
// You must specify a width and height for the image %s
width: this.props.style.width || 1,
height: this.props.style.height || 1,
};
constructor(props) {
super(props);
this.state = {
// set width 1 is for preventing the warning
// You must specify a width and height for the image %s
width: this.props.style.width || 1,
height: this.props.style.height || 1,
};
}
componentDidMount() {
//avoid repaint if width/height is given
if (this.props.style.width || this.props.style.height) {
return;
}
Image.getSize(this.props.source.uri, (w, h) => {
this.setState({width: w, height: h});
});
}
componentDidMount() {
//avoid repaint if width/height is given
if (this.props.style.width || this.props.style.height) {
return;
}
Image.getSize(this.props.source.uri, (w, h) => {
this.setState({ width: w, height: h });
});
render() {
const finalSize = {};
const resize_width =
typeof this.props.resize_width != 'undefined' &&
this.props.resize_width > 0
? this.props.resize_width
: width;
if (this.state.width > resize_width) {
finalSize.width = resize_width;
const ratio = resize_width / this.state.width;
finalSize.height = this.state.height * ratio;
}
const style = Object.assign(
baseStyle,
this.props.style,
this.state,
finalSize
);
let source = {};
if (!finalSize.width || !finalSize.height) {
source = Object.assign(source, this.props.source, this.state);
} else {
source = Object.assign(source, this.props.source, finalSize);
}
render() {
const finalSize = {};
const resize_width =
this.props.resize_width > 0 ? this.props.resize_width : width;
if (this.state.width > resize_width) {
finalSize.width = resize_width;
const ratio = resize_width / this.state.width;
finalSize.height = this.state.height * ratio;
}
const style = Object.assign(
baseStyle,
this.props.style,
this.state,
finalSize
);
let source = {};
if (!finalSize.width || !finalSize.height) {
source = Object.assign(source, this.props.source, this.state);
} else {
source = Object.assign(source, this.props.source, finalSize);
}
return <Image style={style} source={source} />;
}
return <Image style={style} source={source} />;
}
}
import React from 'react';
import { StyleSheet, Text } from 'react-native';
import {StyleSheet, Text} from 'react-native';
import htmlparser from 'htmlparser2-without-node-native';

@@ -9,183 +9,183 @@ import entities from 'entities';

const defaultOpts = {
lineBreak: '\n',
paragraphBreak: '\n\n',
bullet: '\u2022 ',
TextComponent: Text,
textComponentProps: null,
NodeComponent: Text,
nodeComponentProps: null,
lineBreak: '\n',
paragraphBreak: '\n\n',
bullet: '\u2022 ',
TextComponent: Text,
textComponentProps: null,
NodeComponent: Text,
nodeComponentProps: null,
};
const Img = props => {
const width =
parseInt(props.attribs['width'], 10) ||
parseInt(props.attribs['data-width'], 10) ||
0;
const height =
parseInt(props.attribs['height'], 10) ||
parseInt(props.attribs['data-height'], 10) ||
0;
const width =
parseInt(props.attribs['width'], 10) ||
parseInt(props.attribs['data-width'], 10) ||
0;
const height =
parseInt(props.attribs['height'], 10) ||
parseInt(props.attribs['data-height'], 10) ||
0;
const imgStyle = {
width,
height,
};
const imgStyle = {
width,
height,
};
const source = {
uri: props.attribs.src,
width,
height,
};
return (
<AutoSizedImage
resize_width={props.resize_width}
source={source}
style={imgStyle}
/>
);
const source = {
uri: props.attribs.src,
width,
height,
};
return (
<AutoSizedImage
resize_width={props.resize_width}
source={source}
style={imgStyle}
/>
);
};
export default function htmlToElement(rawHtml, customOpts = {}, done) {
const opts = {
...defaultOpts,
...customOpts,
};
const opts = {
...defaultOpts,
...customOpts,
};
function inheritedStyle(parent) {
if (!parent) return null;
const style = StyleSheet.flatten(opts.styles[parent.name]) || {};
const parentStyle = inheritedStyle(parent.parent) || {};
return { ...parentStyle, ...style };
}
function inheritedStyle(parent) {
if (!parent) return null;
const style = StyleSheet.flatten(opts.styles[parent.name]) || {};
const parentStyle = inheritedStyle(parent.parent) || {};
return {...parentStyle, ...style};
}
function domToElement(dom, parent) {
if (!dom) return null;
function domToElement(dom, parent) {
if (!dom) return null;
const renderNode = opts.customRenderer;
let orderedListCounter = 1;
const renderNode = opts.customRenderer;
let orderedListCounter = 1;
return dom.map((node, index, list) => {
if (renderNode) {
const rendered = renderNode(node, index, list, parent, domToElement);
if (rendered || rendered === null) return rendered;
}
return dom.map((node, index, list) => {
if (renderNode) {
const rendered = renderNode(node, index, list, parent, domToElement);
if (rendered || rendered === null) return rendered;
}
const { TextComponent } = opts;
const {TextComponent} = opts;
if (node.type === 'text') {
const defaultStyle = opts.textComponentProps
? opts.textComponentProps.style
: null;
const customStyle = inheritedStyle(parent);
if (node.type === 'text') {
const defaultStyle = opts.textComponentProps
? opts.textComponentProps.style
: null;
const customStyle = inheritedStyle(parent);
return (
<TextComponent
{...opts.textComponentProps}
key={index}
style={[defaultStyle, customStyle]}
>
{entities.decodeHTML(node.data)}
</TextComponent>
);
}
return (
<TextComponent
{...opts.textComponentProps}
key={index}
style={[defaultStyle, customStyle]}
>
{entities.decodeHTML(node.data)}
</TextComponent>
);
}
if (node.type === 'tag') {
if (node.name === 'img') {
return (
<Img
key={index}
resize_width={opts.resize_width}
attribs={node.attribs}
/>
);
}
if (node.type === 'tag') {
if (node.name === 'img') {
return (
<Img
key={index}
attribs={node.attribs}
resize_width={opts.resize_width}
/>
);
}
let linkPressHandler = null;
let linkLongPressHandler = null;
if (node.name === 'a' && node.attribs && node.attribs.href) {
linkPressHandler = () =>
opts.linkHandler(entities.decodeHTML(node.attribs.href));
if (opts.linkLongPressHandler) {
linkLongPressHandler = () =>
opts.linkLongPressHandler(entities.decodeHTML(node.attribs.href));
}
}
let linkPressHandler = null;
let linkLongPressHandler = null;
if (node.name === 'a' && node.attribs && node.attribs.href) {
linkPressHandler = () =>
opts.linkHandler(entities.decodeHTML(node.attribs.href));
if (opts.linkLongPressHandler) {
linkLongPressHandler = () =>
opts.linkLongPressHandler(entities.decodeHTML(node.attribs.href));
}
}
let linebreakBefore = null;
let linebreakAfter = null;
if (opts.addLineBreaks) {
switch (node.name) {
case 'pre':
linebreakBefore = opts.lineBreak;
break;
case 'p':
if (index < list.length - 1) {
linebreakAfter = opts.paragraphBreak;
}
break;
case 'br':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
linebreakAfter = opts.lineBreak;
break;
}
}
let linebreakBefore = null;
let linebreakAfter = null;
if (opts.addLineBreaks) {
switch (node.name) {
case 'pre':
linebreakBefore = opts.lineBreak;
break;
case 'p':
if (index < list.length - 1) {
linebreakAfter = opts.paragraphBreak;
}
break;
case 'br':
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
linebreakAfter = opts.lineBreak;
break;
}
}
let listItemPrefix = null;
if (node.name === 'li') {
const defaultStyle = opts.textComponentProps
? opts.textComponentProps.style
: null;
const customStyle = inheritedStyle(parent);
let listItemPrefix = null;
if (node.name === 'li') {
const defaultStyle = opts.textComponentProps
? opts.textComponentProps.style
: null;
const customStyle = inheritedStyle(parent);
if (!parent) {
listItemPrefix = null;
} else if (parent.name === 'ol') {
listItemPrefix = (
<TextComponent style={[defaultStyle, customStyle]}>
{`${orderedListCounter++}. `}
</TextComponent>
);
} else if (parent.name === 'ul') {
listItemPrefix = (
<TextComponent style={[defaultStyle, customStyle]}>
{opts.bullet}
</TextComponent>
);
}
if (opts.addLineBreaks && index < list.length - 1) {
linebreakAfter = opts.lineBreak;
}
}
if (!parent) {
listItemPrefix = null;
} else if (parent.name === 'ol') {
listItemPrefix = (
<TextComponent style={[defaultStyle, customStyle]}>
{`${orderedListCounter++}. `}
</TextComponent>
);
} else if (parent.name === 'ul') {
listItemPrefix = (
<TextComponent style={[defaultStyle, customStyle]}>
{opts.bullet}
</TextComponent>
);
}
if (opts.addLineBreaks && index < list.length - 1) {
linebreakAfter = opts.lineBreak;
}
}
const { NodeComponent, styles } = opts;
const {NodeComponent, styles} = opts;
return (
<NodeComponent
{...opts.nodeComponentProps}
key={index}
onPress={linkPressHandler}
style={!node.parent ? styles[node.name] : null}
onLongPress={linkLongPressHandler}
>
{linebreakBefore}
{listItemPrefix}
{domToElement(node.children, node)}
{linebreakAfter}
</NodeComponent>
);
}
});
}
return (
<NodeComponent
{...opts.nodeComponentProps}
key={index}
onPress={linkPressHandler}
style={!node.parent ? styles[node.name] : null}
onLongPress={linkLongPressHandler}
>
{linebreakBefore}
{listItemPrefix}
{domToElement(node.children, node)}
{linebreakAfter}
</NodeComponent>
);
}
});
}
const handler = new htmlparser.DomHandler(function (err, dom) {
if (err) done(err);
done(null, domToElement(dom));
});
const parser = new htmlparser.Parser(handler);
parser.write(rawHtml);
parser.done();
const handler = new htmlparser.DomHandler(function(err, dom) {
if (err) done(err);
done(null, domToElement(dom));
});
const parser = new htmlparser.Parser(handler);
parser.write(rawHtml);
parser.done();
}
+143
-143

@@ -1,178 +0,178 @@

import React, { PureComponent } from 'react';
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import htmlToElement from './htmlToElement';
import { Linking, Platform, StyleSheet, View } from 'react-native';
import {Linking, Platform, StyleSheet, View} from 'react-native';
const boldStyle = { fontWeight: 'bold' };
const italicStyle = { fontStyle: 'italic' };
const underlineStyle = { textDecorationLine: 'underline' };
const strikethroughStyle = { textDecorationLine: 'line-through' };
const codeStyle = { fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace' };
const boldStyle = {fontWeight: 'bold'};
const italicStyle = {fontStyle: 'italic'};
const underlineStyle = {textDecorationLine: 'underline'};
const strikethroughStyle = {textDecorationLine: 'line-through'};
const codeStyle = {fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace'};
const baseStyles = StyleSheet.create({
b: boldStyle,
strong: boldStyle,
i: italicStyle,
em: italicStyle,
u: underlineStyle,
s: strikethroughStyle,
strike: strikethroughStyle,
pre: codeStyle,
code: codeStyle,
a: {
fontWeight: 'bold',
color: '#007AFF',
},
h1: { fontWeight: 'bold', fontSize: 36 },
h2: { fontWeight: 'bold', fontSize: 30 },
h3: { fontWeight: 'bold', fontSize: 24 },
h4: { fontWeight: 'bold', fontSize: 18 },
h5: { fontWeight: 'bold', fontSize: 14 },
h6: { fontWeight: 'bold', fontSize: 12 },
b: boldStyle,
strong: boldStyle,
i: italicStyle,
em: italicStyle,
u: underlineStyle,
s: strikethroughStyle,
strike: strikethroughStyle,
pre: codeStyle,
code: codeStyle,
a: {
fontWeight: 'bold',
color: '#007AFF',
},
h1: {fontWeight: 'bold', fontSize: 36},
h2: {fontWeight: 'bold', fontSize: 30},
h3: {fontWeight: 'bold', fontSize: 24},
h4: {fontWeight: 'bold', fontSize: 18},
h5: {fontWeight: 'bold', fontSize: 14},
h6: {fontWeight: 'bold', fontSize: 12},
});
const htmlToElementOptKeys = [
'lineBreak',
'paragraphBreak',
'bullet',
'TextComponent',
'textComponentProps',
'NodeComponent',
'nodeComponentProps',
'lineBreak',
'paragraphBreak',
'bullet',
'TextComponent',
'textComponentProps',
'NodeComponent',
'nodeComponentProps',
];
class HtmlView extends PureComponent {
constructor() {
super();
this.state = {
element: null,
};
}
constructor() {
super();
this.state = {
element: null,
};
}
componentDidMount() {
this.mounted = true;
this.startHtmlRender(this.props.value);
}
componentDidMount() {
this.mounted = true;
this.startHtmlRender(this.props.value);
}
componentDidUpdate(prevProps) {
if (
this.props.resize_width !== prevProps.resize_width ||
this.props.value !== prevProps.value ||
this.props.stylesheet !== prevProps.stylesheet ||
this.props.textComponentProps !== prevProps.textComponentProps ||
this.props.nodeComponentProps !== prevProps.nodeComponentProps
) {
this.startHtmlRender(
this.props.resize_width,
this.props.value,
this.props.stylesheet,
this.props.textComponentProps,
this.props.nodeComponentProps
);
}
componentDidUpdate(prevProps) {
if (
this.props.value !== prevProps.value ||
this.props.stylesheet !== prevProps.stylesheet ||
this.props.textComponentProps !== prevProps.textComponentProps ||
this.props.nodeComponentProps !== prevProps.nodeComponentProps
) {
this.startHtmlRender(
this.props.value,
this.props.stylesheet,
this.props.textComponentProps,
this.props.nodeComponentProps,
this.props.resize_width
);
}
}
componentWillUnmount() {
this.mounted = false;
}
componentWillUnmount() {
this.mounted = false;
}
startHtmlRender(
resize_width,
value,
style,
textComponentProps,
nodeComponentProps
) {
const {
addLineBreaks,
onLinkPress,
onLinkLongPress,
stylesheet,
renderNode,
onError,
} = this.props;
startHtmlRender(
value,
style,
textComponentProps,
nodeComponentProps,
resize_width
) {
const {
addLineBreaks,
onLinkPress,
onLinkLongPress,
stylesheet,
renderNode,
onError,
} = this.props;
if (!value) {
this.setState({ element: null });
}
if (!value) {
this.setState({element: null});
}
const opts = {
addLineBreaks,
linkHandler: onLinkPress,
linkLongPressHandler: onLinkLongPress,
styles: { ...baseStyles, ...stylesheet, ...style },
customRenderer: renderNode,
};
const opts = {
addLineBreaks,
linkHandler: onLinkPress,
linkLongPressHandler: onLinkLongPress,
styles: {...baseStyles, ...stylesheet, ...style},
customRenderer: renderNode,
};
htmlToElementOptKeys.forEach(key => {
if (typeof this.props[key] !== 'undefined') {
opts[key] = this.props[key];
}
});
htmlToElementOptKeys.forEach(key => {
if (typeof this.props[key] !== 'undefined') {
opts[key] = this.props[key];
}
});
if (resize_width) {
opts.resize_width = resize_width;
}
if (resize_width) {
opts.resize_width = resize_width;
}
if (textComponentProps) {
opts.textComponentProps = textComponentProps;
}
if (textComponentProps) {
opts.textComponentProps = textComponentProps;
}
if (nodeComponentProps) {
opts.nodeComponentProps = nodeComponentProps;
}
if (nodeComponentProps) {
opts.nodeComponentProps = nodeComponentProps;
}
htmlToElement(value, opts, (err, element) => {
if (err) {
onError(err);
}
htmlToElement(value, opts, (err, element) => {
if (err) {
onError(err);
}
if (this.mounted) {
this.setState({ element });
}
});
}
if (this.mounted) {
this.setState({element});
}
});
}
render() {
const { RootComponent, style } = this.props;
const { element } = this.state;
if (element) {
return (
<RootComponent {...this.props.rootComponentProps} style={style}>
{element}
</RootComponent>
);
}
return <RootComponent {...this.props.rootComponentProps} style={style} />;
render() {
const {RootComponent, style} = this.props;
const {element} = this.state;
if (element) {
return (
<RootComponent {...this.props.rootComponentProps} style={style}>
{element}
</RootComponent>
);
}
return <RootComponent {...this.props.rootComponentProps} style={style} />;
}
}
HtmlView.propTypes = {
addLineBreaks: PropTypes.bool,
bullet: PropTypes.string,
lineBreak: PropTypes.string,
NodeComponent: PropTypes.func,
nodeComponentProps: PropTypes.object,
onError: PropTypes.func,
onLinkPress: PropTypes.func,
onLinkLongPress: PropTypes.func,
paragraphBreak: PropTypes.string,
renderNode: PropTypes.func,
RootComponent: PropTypes.func,
rootComponentProps: PropTypes.object,
style: PropTypes.object,
stylesheet: PropTypes.object,
TextComponent: PropTypes.func,
textComponentProps: PropTypes.object,
value: PropTypes.string,
addLineBreaks: PropTypes.bool,
bullet: PropTypes.string,
lineBreak: PropTypes.string,
NodeComponent: PropTypes.func,
nodeComponentProps: PropTypes.object,
onError: PropTypes.func,
onLinkPress: PropTypes.func,
onLinkLongPress: PropTypes.func,
paragraphBreak: PropTypes.string,
renderNode: PropTypes.func,
RootComponent: PropTypes.func,
rootComponentProps: PropTypes.object,
style: PropTypes.object,
stylesheet: PropTypes.object,
TextComponent: PropTypes.func,
textComponentProps: PropTypes.object,
value: PropTypes.string,
resize_width: PropTypes.number,
};
HtmlView.defaultProps = {
addLineBreaks: true,
onLinkPress: url => Linking.openURL(url),
onLinkLongPress: null,
onError: console.error.bind(console),
RootComponent: element => <View {...element} />, // eslint-disable-line react/display-name
addLineBreaks: true,
onLinkPress: url => Linking.openURL(url),
onLinkLongPress: null,
onError: console.error.bind(console),
RootComponent: element => <View {...element} />, // eslint-disable-line react/display-name
};
export default HtmlView;
{
"name": "@chainplatform/react-native-htmlview",
"version": "0.17.1",
"version": "0.17.2",
"description": "React Native render HTML view, support React Native Web. This project fork from https://github.com/jsdf/react-native-htmlview",

@@ -14,9 +14,9 @@ "main": "index.js",

"devDependencies": {
"@babel/runtime": "^7.20.0",
"babel-preset-expo": "^5.0.0",
"@react-native/babel-preset": "0.74.85",
"@babel/runtime": "^7.5.5",
"babel-preset-expo": "^5.2.0",
"jest": "^29.7.0",
"prettier": "^1.18.2",
"react": "^18.3.1",
"react-native": "0.74.3"
"react": "18.2.0",
"react-native": "^0.72.6",
"react-test-renderer": "18.2.0"
},

@@ -50,2 +50,2 @@ "jest": {

}
}
}