diff options
author | Nolan Lawson <nolan@nolanlawson.com> | 2017-07-07 16:57:22 -0700 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2017-07-08 01:57:22 +0200 |
commit | 63b77f23202a6dece419e2eb7180395b2e276b09 (patch) | |
tree | cfde074ee8cbecc3efa41ae85100f7c020b22e84 | |
parent | 8fecd8010801c17d0d086fbb27d4d9a67ccbb6af (diff) |
Avoid using getBoundingClientRect to calculate height (#4001)
4 files changed, 30 insertions, 20 deletions
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 18ce0198e..df771f5a8 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -17,6 +17,7 @@ import { MediaGallery, VideoPlayer } from '../features/ui/util/async-components' // We use the component (and not the container) since we do not want // to use the progress bar to show download progress import Bundle from '../features/ui/components/bundle'; +import getRectFromEntry from '../features/ui/util/get_rect_from_entry'; export default class Status extends ImmutablePureComponent { @@ -101,6 +102,11 @@ export default class Status extends ImmutablePureComponent { } handleIntersection = (entry) => { + if (this.node && this.node.children.length !== 0) { + // save the height of the fully-rendered element + this.height = getRectFromEntry(entry).height; + } + // Edge 15 doesn't support isIntersecting, but we can infer it // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12156111/ // https://github.com/WICG/IntersectionObserver/issues/211 @@ -129,15 +135,8 @@ export default class Status extends ImmutablePureComponent { this.setState((prevState) => ({ isHidden: !prevState.isIntersecting })); } - saveHeight = () => { - if (this.node && this.node.children.length !== 0) { - this.height = this.node.getBoundingClientRect().height; - } - } - handleRef = (node) => { this.node = node; - this.saveHeight(); } handleClick = () => { @@ -213,13 +212,13 @@ export default class Status extends ImmutablePureComponent { } else if (status.getIn(['media_attachments', 0, 'type']) === 'video') { media = ( - <Bundle fetchComponent={VideoPlayer} loading={this.renderLoadingVideoPlayer} onRender={this.saveHeight} > + <Bundle fetchComponent={VideoPlayer} loading={this.renderLoadingVideoPlayer} > {Component => <Component media={status.getIn(['media_attachments', 0])} sensitive={status.get('sensitive')} onOpenVideo={this.props.onOpenVideo} />} </Bundle> ); } else { media = ( - <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} onRender={this.saveHeight} > + <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} > {Component => <Component media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />} </Bundle> ); @@ -246,7 +245,7 @@ export default class Status extends ImmutablePureComponent { </a> </div> - <StatusContent status={status} onClick={this.handleClick} expanded={isExpanded} onExpandedToggle={this.handleExpandedToggle} onHeightUpdate={this.saveHeight} /> + <StatusContent status={status} onClick={this.handleClick} expanded={isExpanded} onExpandedToggle={this.handleExpandedToggle} /> {media} diff --git a/app/javascript/mastodon/components/status_content.js b/app/javascript/mastodon/components/status_content.js index 78656571d..02b4c8402 100644 --- a/app/javascript/mastodon/components/status_content.js +++ b/app/javascript/mastodon/components/status_content.js @@ -17,7 +17,6 @@ export default class StatusContent extends React.PureComponent { status: ImmutablePropTypes.map.isRequired, expanded: PropTypes.bool, onExpandedToggle: PropTypes.func, - onHeightUpdate: PropTypes.func, onClick: PropTypes.func, }; @@ -56,9 +55,6 @@ export default class StatusContent extends React.PureComponent { } componentDidUpdate () { - if (this.props.onHeightUpdate) { - this.props.onHeightUpdate(); - } this._updateStatusLinks(); } diff --git a/app/javascript/mastodon/features/ui/components/bundle.js b/app/javascript/mastodon/features/ui/components/bundle.js index e69a32f47..3eed446fe 100644 --- a/app/javascript/mastodon/features/ui/components/bundle.js +++ b/app/javascript/mastodon/features/ui/components/bundle.js @@ -12,7 +12,6 @@ class Bundle extends React.Component { error: PropTypes.func, children: PropTypes.func.isRequired, renderDelay: PropTypes.number, - onRender: PropTypes.func, onFetch: PropTypes.func, onFetchSuccess: PropTypes.func, onFetchFail: PropTypes.func, @@ -22,7 +21,6 @@ class Bundle extends React.Component { loading: emptyComponent, error: emptyComponent, renderDelay: 0, - onRender: noop, onFetch: noop, onFetchSuccess: noop, onFetchFail: noop, @@ -43,10 +41,6 @@ class Bundle extends React.Component { } } - componentDidUpdate () { - this.props.onRender(); - } - componentWillUnmount () { if (this.timeout) { clearTimeout(this.timeout); diff --git a/app/javascript/mastodon/features/ui/util/get_rect_from_entry.js b/app/javascript/mastodon/features/ui/util/get_rect_from_entry.js new file mode 100644 index 000000000..c266cd7dc --- /dev/null +++ b/app/javascript/mastodon/features/ui/util/get_rect_from_entry.js @@ -0,0 +1,21 @@ + +// Get the bounding client rect from an IntersectionObserver entry. +// This is to work around a bug in Chrome: https://crbug.com/737228 + +let hasBoundingRectBug; + +function getRectFromEntry(entry) { + if (typeof hasBoundingRectBug !== 'boolean') { + const boundingRect = entry.target.getBoundingClientRect(); + const observerRect = entry.boundingClientRect; + hasBoundingRectBug = boundingRect.height !== observerRect.height || + boundingRect.top !== observerRect.top || + boundingRect.width !== observerRect.width || + boundingRect.bottom !== observerRect.bottom || + boundingRect.left !== observerRect.left || + boundingRect.right !== observerRect.right; + } + return hasBoundingRectBug ? entry.target.getBoundingClientRect() : entry.boundingClientRect; +} + +export default getRectFromEntry; |