diff --git a/app/renderer/components/frame/frame.js b/app/renderer/components/frame/frame.js
index e190d58aa44..63bbcc7859f 100644
--- a/app/renderer/components/frame/frame.js
+++ b/app/renderer/components/frame/frame.js
@@ -859,12 +859,15 @@ class Frame extends React.Component {
const props = {}
// used in renderer
+ props.transitionState = ownProps.transitionState
props.partition = frameStateUtil.getPartition(frame)
props.isFullScreen = frame.get('isFullScreen')
props.isPreview = frame.get('key') === currentWindow.get('previewFrameKey')
props.isActive = frameStateUtil.isFrameKeyActive(currentWindow, frame.get('key'))
props.showFullScreenWarning = frame.get('showFullScreenWarning')
props.location = location
+ props.isDefaultNewTabLocation = location === 'about:newtab'
+ props.isBlankLocation = location === 'about:blank'
props.tabId = tabId
props.showMessageBox = tabMessageBoxState.hasMessageBoxDetail(state, tabId)
props.isFocused = isFocused(state)
@@ -906,7 +909,16 @@ class Frame extends React.Component {
return props
}
+ getTransitionStateClassName (stateName) {
+ if (!stateName) {
+ return null
+ } else {
+ return `is${stateName[0].toUpperCase()}${stateName.slice(1)}`
+ }
+ }
+
render () {
+ const transitionClassName = this.getTransitionStateClassName(this.props.transitionState)
return
{
this.props.isFullScreen && this.props.showFullScreenWarning
diff --git a/app/renderer/components/main/main.js b/app/renderer/components/main/main.js
index 1a3e65793a8..aeefb98da7c 100644
--- a/app/renderer/components/main/main.js
+++ b/app/renderer/components/main/main.js
@@ -17,6 +17,7 @@ const contextMenus = require('../../../../js/contextMenus')
const {getSetting} = require('../../../../js/settings')
// Components
+const { Transition, TransitionGroup } = require('react-transition-group')
const Navigator = require('../navigation/navigator')
const Frame = require('../frame/frame')
const TabPages = require('../tabs/tabPages')
@@ -733,15 +734,27 @@ class Main extends React.Component {
}
-
+
{
this.props.sortedFrames.map((frameKey) =>
- )
+ // after how long (ms)
+ // should the state 'entering' switch to 'entered'
+ // and also how long should state switch from 'exiting'
+ // to the component actually being removed
+ timeout={150}>
+ {
+ (transitionState) =>
+
+ }
+
+ )
}
-
+
{
this.props.showDownloadBar
diff --git a/less/window.less b/less/window.less
index e943183db1f..33ee3d82255 100644
--- a/less/window.less
+++ b/less/window.less
@@ -62,16 +62,66 @@ html,
.frameWrapper {
height: 100%;
width: 100%;
- z-index: @zindexWindow;
+
position: absolute;
top: 0;
left: 0;
// Needed to be able to click and drag to select content in pages.
user-select: none;
+ // default frame background
+ --frame-bg: #fff;
+ // custom frame background(s)
+ &.isDefaultNewTabLocation {
+ // matches tab dashboard background
+ // will also show when about:newtab === about:blank
+ --frame-bg: #222;
+ }
+ // Webviews can cause flickers w/ Chrome v49 if left visible
+ // in the background. This also has a major benefit for background
+ // tabs that have video and animations in them.
+ visibility: hidden;
+ // delay frames getting hidden when new tabs show up
+ // in order to avoid showing 0 frames and just the window
+ // background
+ // whilst this does also affect visibility when switching tabs,
+ // z-index ensures the delayed-hidden tab is not visible
+ // Note that this value can be as large as we want, it does not
+ // need to match the timeout specified in the frame's element
+ // (in renderer main.js). However, there is no reason to set it higher than that.
+ transition: visibility 0s linear 150ms;
+ // 1000
+ z-index: @zindexWindow;
+ &:not(.isActive) {
+ // 900
+ z-index: @zindexWindowNotActive;
+ }
+ &.isPreview {
+ background: #222;
+ // 1100
+ z-index: @zindexWindowIsPreview;
+ }
+ // show frame when active or preview
+ &.isActive,
+ &.isPreview,
+ // keep window contents around when exiting, to allow
+ // time for next active frame to be shown
+ &.isExiting {
+ visibility: visible;
+ // show instantly
+ transition-delay: 0s;
+ }
+ // hide frame whilst it's figuring out which location to be
+ // note: that isEntering is timed-out at a value set in renderer main.js
+ // but isBlankLocation will change at the exact moment that the frame
+ // has an actual location
+ &.isEntering.isBlankLocation {
+ visibility: hidden;
+ transition-delay: 0s;
+ }
webview {
- background-color: #fff;
+ background-color: var(--frame-bg);
border: 0;
height: 100%;
outline: none;
@@ -89,21 +139,6 @@ html,
}
}
- &:not(.isActive) {
- z-index: @zindexWindowNotActive;
-
- &.isPreview {
- background: gray;
- z-index: @zindexWindowIsPreview;
- }
-
- // Webviews can cause flickers w/ Chrome v49 if left visible
- // in the background. This also has a major benefit for background
- // tabs that have video and animations in them.
- &:not(.isPreview) {
- visibility: hidden;
- }
- }
}
.hrefPreview {
diff --git a/package-lock.json b/package-lock.json
index badbe14f71c..47c12da8e61 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2702,6 +2702,11 @@
"integrity": "sha1-CdekApCKpw39vq1T5YU/x50+8hw=",
"dev": true
},
+ "chain-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz",
+ "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w="
+ },
"chainsaw": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
@@ -4771,6 +4776,11 @@
}
}
},
+ "dom-helpers": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.2.1.tgz",
+ "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo="
+ },
"dom-serializer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
@@ -16617,6 +16627,19 @@
"object-assign": "4.1.1"
}
},
+ "react-transition-group": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.2.1.tgz",
+ "integrity": "sha512-q54UBM22bs/CekG8r3+vi9TugSqh0t7qcEVycaRc9M0p0aCEu+h6rp/RFiW7fHfgd1IKpd9oILFTl5QK+FpiPA==",
+ "requires": {
+ "chain-function": "1.0.0",
+ "classnames": "2.2.5",
+ "dom-helpers": "3.2.1",
+ "loose-envify": "1.3.1",
+ "prop-types": "15.6.0",
+ "warning": "3.0.0"
+ }
+ },
"read-all-stream": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz",
@@ -19954,6 +19977,14 @@
"integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
"dev": true
},
+ "warning": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+ "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+ "requires": {
+ "loose-envify": "1.3.1"
+ }
+ },
"watchpack": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
diff --git a/package.json b/package.json
index e09eefb2113..bd8ff389691 100644
--- a/package.json
+++ b/package.json
@@ -120,6 +120,7 @@
"react-dnd-html5-backend": "^2.1.2",
"react-dom": "^15.5.4",
"react-select": "^0.9.1",
+ "react-transition-group": "^2.2.1",
"snazzy": "^7.0.0",
"string.prototype.endswith": "^0.2.0",
"string.prototype.startswith": "^0.2.0",