about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNolan Lawson <nolan@nolanlawson.com>2017-07-07 16:57:22 -0700
committerEugen Rochko <eugen@zeonfederated.com>2017-07-08 01:57:22 +0200
commit63b77f23202a6dece419e2eb7180395b2e276b09 (patch)
treecfde074ee8cbecc3efa41ae85100f7c020b22e84
parent8fecd8010801c17d0d086fbb27d4d9a67ccbb6af (diff)
Avoid using getBoundingClientRect to calculate height (#4001)
-rw-r--r--app/javascript/mastodon/components/status.js19
-rw-r--r--app/javascript/mastodon/components/status_content.js4
-rw-r--r--app/javascript/mastodon/features/ui/components/bundle.js6
-rw-r--r--app/javascript/mastodon/features/ui/util/get_rect_from_entry.js21
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;