about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorNolan Lawson <nolan@nolanlawson.com>2017-10-01 18:01:01 -0700
committerEugen Rochko <eugen@zeonfederated.com>2017-10-02 03:01:01 +0200
commitc567c874537b733a3e15625ad01eb0ae0ced8f4e (patch)
tree8a19679f120a44b1db13ad36c4d928922605afad /app
parent47ecd652d3f8256a191401f005d42760e858e6de (diff)
Toggle contain:strict on fullscreen (#5159)
* Toggle contain:strict on fullscreen

* Fix scss lint issue

* fix scss whitespace lint issue
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/components/scrollable_list.js11
-rw-r--r--app/javascript/mastodon/features/ui/util/fullscreen.js46
-rw-r--r--app/javascript/mastodon/features/video/index.js30
-rw-r--r--app/javascript/styles/components.scss10
4 files changed, 67 insertions, 30 deletions
diff --git a/app/javascript/mastodon/components/scrollable_list.js b/app/javascript/mastodon/components/scrollable_list.js
index ff0540e5d..c6b588765 100644
--- a/app/javascript/mastodon/components/scrollable_list.js
+++ b/app/javascript/mastodon/components/scrollable_list.js
@@ -6,6 +6,8 @@ import LoadMore from './load_more';
 import IntersectionObserverWrapper from '../features/ui/util/intersection_observer_wrapper';
 import { throttle } from 'lodash';
 import { List as ImmutableList } from 'immutable';
+import classNames from 'classnames';
+import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../features/ui/util/fullscreen';
 
 export default class ScrollableList extends PureComponent {
 
@@ -66,6 +68,7 @@ export default class ScrollableList extends PureComponent {
   componentDidMount () {
     this.attachScrollListener();
     this.attachIntersectionObserver();
+    attachFullscreenListener(this.onFullScreenChange);
 
     // Handle initial scroll posiiton
     this.handleScroll();
@@ -92,6 +95,11 @@ export default class ScrollableList extends PureComponent {
   componentWillUnmount () {
     this.detachScrollListener();
     this.detachIntersectionObserver();
+    detachFullscreenListener(this.onFullScreenChange);
+  }
+
+  onFullScreenChange = () => {
+    this.setState({ fullscreen: isFullscreen() });
   }
 
   attachIntersectionObserver () {
@@ -165,6 +173,7 @@ export default class ScrollableList extends PureComponent {
 
   render () {
     const { children, scrollKey, trackScroll, shouldUpdateScroll, isLoading, hasMore, prepend, emptyMessage } = this.props;
+    const { fullscreen } = this.state;
     const childrenCount = React.Children.count(children);
 
     const loadMore     = (hasMore && childrenCount > 0) ? <LoadMore visible={!isLoading} onClick={this.handleLoadMore} /> : null;
@@ -172,7 +181,7 @@ export default class ScrollableList extends PureComponent {
 
     if (isLoading || childrenCount > 0 || !emptyMessage) {
       scrollableArea = (
-        <div className='scrollable' ref={this.setRef} onMouseMove={this.handleMouseMove} onMouseLeave={this.handleMouseLeave}>
+        <div className={classNames('scrollable', { fullscreen })} ref={this.setRef} onMouseMove={this.handleMouseMove} onMouseLeave={this.handleMouseLeave}>
           <div role='feed' className='item-list' onKeyDown={this.handleKeyDown}>
             {prepend}
 
diff --git a/app/javascript/mastodon/features/ui/util/fullscreen.js b/app/javascript/mastodon/features/ui/util/fullscreen.js
new file mode 100644
index 000000000..cf5d0cf98
--- /dev/null
+++ b/app/javascript/mastodon/features/ui/util/fullscreen.js
@@ -0,0 +1,46 @@
+// APIs for normalizing fullscreen operations. Note that Edge uses
+// the WebKit-prefixed APIs currently (as of Edge 16).
+
+export const isFullscreen = () => document.fullscreenElement ||
+  document.webkitFullscreenElement ||
+  document.mozFullScreenElement;
+
+export const exitFullscreen = () => {
+  if (document.exitFullscreen) {
+    document.exitFullscreen();
+  } else if (document.webkitExitFullscreen) {
+    document.webkitExitFullscreen();
+  } else if (document.mozCancelFullScreen) {
+    document.mozCancelFullScreen();
+  }
+};
+
+export const requestFullscreen = el => {
+  if (el.requestFullscreen) {
+    el.requestFullscreen();
+  } else if (el.webkitRequestFullscreen) {
+    el.webkitRequestFullscreen();
+  } else if (el.mozRequestFullScreen) {
+    el.mozRequestFullScreen();
+  }
+};
+
+export const attachFullscreenListener = (listener) => {
+  if ('onfullscreenchange' in document) {
+    document.addEventListener('fullscreenchange', listener);
+  } else if ('onwebkitfullscreenchange' in document) {
+    document.addEventListener('webkitfullscreenchange', listener);
+  } else if ('onmozfullscreenchange' in document) {
+    document.addEventListener('mozfullscreenchange', listener);
+  }
+};
+
+export const detachFullscreenListener = (listener) => {
+  if ('onfullscreenchange' in document) {
+    document.removeEventListener('fullscreenchange', listener);
+  } else if ('onwebkitfullscreenchange' in document) {
+    document.removeEventListener('webkitfullscreenchange', listener);
+  } else if ('onmozfullscreenchange' in document) {
+    document.removeEventListener('mozfullscreenchange', listener);
+  }
+};
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 069264ef5..7502dda8b 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -3,6 +3,7 @@ import PropTypes from 'prop-types';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { throttle } from 'lodash';
 import classNames from 'classnames';
+import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
 
 const messages = defineMessages({
   play: { id: 'video.play', defaultMessage: 'Play' },
@@ -69,35 +70,6 @@ const getPointerPosition = (el, event) => {
   return position;
 };
 
-const isFullscreen = () => document.fullscreenElement ||
-  document.webkitFullscreenElement ||
-  document.mozFullScreenElement ||
-  document.msFullscreenElement;
-
-const exitFullscreen = () => {
-  if (document.exitFullscreen) {
-    document.exitFullscreen();
-  } else if (document.webkitExitFullscreen) {
-    document.webkitExitFullscreen();
-  } else if (document.mozCancelFullScreen) {
-    document.mozCancelFullScreen();
-  } else if (document.msExitFullscreen) {
-    document.msExitFullscreen();
-  }
-};
-
-const requestFullscreen = el => {
-  if (el.requestFullscreen) {
-    el.requestFullscreen();
-  } else if (el.webkitRequestFullscreen) {
-    el.webkitRequestFullscreen();
-  } else if (el.mozRequestFullScreen) {
-    el.mozRequestFullScreen();
-  } else if (el.msRequestFullscreen) {
-    el.msRequestFullscreen();
-  }
-};
-
 @injectIntl
 export default class Video extends React.PureComponent {
 
diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss
index caa7c0787..48d6e0c4d 100644
--- a/app/javascript/styles/components.scss
+++ b/app/javascript/styles/components.scss
@@ -1674,6 +1674,16 @@
   &.optionally-scrollable {
     overflow-y: auto;
   }
+
+  @supports(display: grid) { // hack to fix Chrome <57
+    contain: strict;
+  }
+}
+
+.scrollable.fullscreen {
+  @supports(display: grid) { // hack to fix Chrome <57
+    contain: none;
+  }
 }
 
 .column-back-button {