Skip to content

Commit

Permalink
feat: a revamped scalable HTMLImage component
Browse files Browse the repository at this point in the history
BREAKING: imagesMaxWidth prop is discontinued in favor of contentWidth and
computeImagesMaxWidth. See RFC001 for an exhaustive description.

This patch offers a rewrite of the HTMLImage component to get a close
match with RFC001, “a deterministic approach to images scaling”. The only
part of this RFC which is unsupported is the unitConverter behavior, which
is planned for a later major release.

In addition to the capabilities defined in the RFC, this patch provides
the following features and behaviors:

- new property enableExperimentalPercentWidth. It allows percent width
  for <img> tags, computed relatively to contentWidth.
- take margins into account when scaling down images;
- support for overriding image styles, including resizeMode;
- support for minWidth, minHeight, maxWidth, maxHeight styles.

This patch also fixes #141, #172 and provides the features offered in
PR #242 and #315.

fixes #141
fixes #172
closes #315
closes #242
  • Loading branch information
jsamr committed Jul 24, 2020
1 parent 5c733e2 commit eff0c8b
Show file tree
Hide file tree
Showing 9 changed files with 1,022 additions and 392 deletions.
220 changes: 112 additions & 108 deletions README.md

Large diffs are not rendered by default.

32 changes: 23 additions & 9 deletions src/HTML.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@ export default class HTML extends PureComponent {
customWrapper: PropTypes.func,
onLinkPress: PropTypes.func,
onParsed: PropTypes.func,
imagesMaxWidth: PropTypes.number,
computeImagesMaxWidth: PropTypes.func,
staticContentMaxWidth: PropTypes.number,
contentWidth: PropTypes.number,
enableExperimentalPercentWidth: PropTypes.bool,
imagesInitialDimensions: PropTypes.shape({
width: PropTypes.number,
height: PropTypes.number
Expand All @@ -57,8 +59,9 @@ export default class HTML extends PureComponent {
decodeEntities: true,
emSize: 14,
ptSize: 1.3,
contentWidth: Dimensions.get('window').width,
staticContentMaxWidth: Dimensions.get('window').width,
imagesMaxWidth: Dimensions.get('window').width,
enableExperimentalPercentWidth: false,
ignoredTags: IGNORED_TAGS,
ignoredStyles: [],
baseFontStyle: { fontSize: 14 },
Expand Down Expand Up @@ -86,15 +89,30 @@ export default class HTML extends PureComponent {
componentDidMount () {
this.mounted = true;
this.registerDOM();
if (__DEV__ && typeof this.props.contentWidth !== 'number') {
console.warn(
"You should always pass contentWidth prop to properly handle screen rotations " +
"and have a seemless support for images scaling. " +
"In the meantime, HTML will fallback to Dimensions.window().width, but its " +
"layout will become inconsistent after screen rotations. " +
"You are encouraged to use useWindowDimensions hook, see: " +
"https://reactnative.dev/docs/usewindowdimensions"
);
}
}

componentWillUnmount() {
this.mounted = false;
}

componentDidUpdate(prevProps, prevState) {
const { html, uri, renderers, tagsStyles, classesStyles } = prevProps;
let doParseDOM = false;
const { html, uri, renderers, tagsStyles, classesStyles, contentWidth, staticContentMaxWidth, computeImagesMaxWidth } = prevProps;
let shouldParseDOM = tagsStyles !== this.props.tagsStyles ||
classesStyles !== this.props.classesStyles ||
contentWidth !== this.props.contentWidth ||
staticContentMaxWidth !== this.props.staticContentMaxWidth ||
computeImagesMaxWidth !== this.props.computeImagesMaxWidth ||
this.state.dom !== prevState.dom;

this.generateDefaultStyles(this.props.baseFontStyle);
if (renderers !== this.props.renderers) {
Expand All @@ -104,11 +122,7 @@ export default class HTML extends PureComponent {
// If the source changed, register the new HTML and parse it
this.registerDOM(this.props);
}
if (tagsStyles !== this.props.tagsStyles || classesStyles !== this.props.classesStyles) {
// If the tagsStyles changed, render again
this.parseDOM(this.state.dom, this.props);
}
if (this.state.dom !== prevState.dom) {
if (shouldParseDOM) {
this.parseDOM(this.state.dom, this.props);
}
}
Expand Down
Loading

0 comments on commit eff0c8b

Please sign in to comment.