Avoid using getBoundingClientRect to calculate height (#4001)
This commit is contained in:
		
							parent
							
								
									8fecd80108
								
							
						
					
					
						commit
						63b77f2320
					
				
					 4 changed files with 30 additions and 20 deletions
				
			
		| 
						 | 
				
			
			@ -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}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
		Reference in a new issue