diff --git a/app/common/state/tabContentState/partitionState.js b/app/common/state/tabContentState/partitionState.js
index c8fc879c2ab..c974987acc3 100644
--- a/app/common/state/tabContentState/partitionState.js
+++ b/app/common/state/tabContentState/partitionState.js
@@ -3,6 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
// State helpers
+const tabUIState = require('../tabUIState')
const frameStateUtil = require('../../../../js/state/frameStateUtil')
// Constants
@@ -54,3 +55,19 @@ module.exports.getMaxAllowedPartitionNumber = (state, frameKey) => {
}
return partitionNumber
}
+
+module.exports.showPartitionIcon = (state, frameKey) => {
+ const frame = frameStateUtil.getFrameByKey(state, frameKey)
+
+ if (frame == null) {
+ if (process.env.NODE_ENV !== 'test') {
+ console.error('Unable to find frame for showPartitionIcon method')
+ }
+ return false
+ }
+
+ return (
+ module.exports.isPartitionTab(state, frameKey) &&
+ tabUIState.showTabEndIcon(state, frameKey)
+ )
+}
diff --git a/app/renderer/components/tabs/content/newSessionIcon.js b/app/renderer/components/tabs/content/newSessionIcon.js
index 303b902661f..0c7fed78225 100644
--- a/app/renderer/components/tabs/content/newSessionIcon.js
+++ b/app/renderer/components/tabs/content/newSessionIcon.js
@@ -1,22 +1,18 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
+* License, v. 2.0. If a copy of the MPL was not distributed with this file,
+* You can obtain one at http://mozilla.org/MPL/2.0/. */
const React = require('react')
const {StyleSheet, css} = require('aphrodite/no-important')
-const Immutable = require('immutable')
// Components
const ReduxComponent = require('../../reduxComponent')
const TabIcon = require('./tabIcon')
// State
+const partitionState = require('../../../../common/state/tabContentState/partitionState')
const tabUIState = require('../../../../common/state/tabUIState')
-
-// Constants
-const {tabs} = require('../../../../../js/constants/config')
-
-// Utils
+const tabState = require('../../../../common/state/tabState')
const frameStateUtil = require('../../../../../js/state/frameStateUtil')
// Styles
@@ -26,45 +22,42 @@ const newSessionSvg = require('../../../../extensions/brave/img/tabs/new_session
class NewSessionIcon extends React.Component {
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
- const frameKey = ownProps.frameKey
- const frame = frameStateUtil.getFrameByKey(currentWindow, frameKey) || Immutable.Map()
- const partition = frame.get('partitionNumber')
- const hasSeconardImage = tabUIState.hasVisibleSecondaryIcon(currentWindow, ownProps.frameKey)
+ const tabId = ownProps.tabId
+ const frameKey = frameStateUtil.getFrameKeyByTabId(currentWindow, tabId)
const props = {}
- // used in renderer
- props.showSessionIcon = !!partition && hasSeconardImage
+ props.isPinned = tabState.isTabPinned(state, tabId)
+ props.showPartitionIcon = partitionState.showPartitionIcon(currentWindow, frameKey)
props.isActive = frameStateUtil.isFrameKeyActive(currentWindow, frameKey)
- props.iconColor = tabUIState.getTabIconColor(currentWindow, frameKey)
- props.partitionNumber = typeof partition === 'string'
- ? partition.replace(/^partition-/i, '')
- : partition
- props.partitionIndicator = props.partitionNumber > tabs.maxAllowedNewSessions
- ? tabs.maxAllowedNewSessions
- : props.partitionNumber
-
- // used in functions
- props.frameKey = frameKey
+ props.textIsWhite = tabUIState.checkIfTextColor(currentWindow, frameKey, 'white')
+ props.partitionNumber = partitionState.getMaxAllowedPartitionNumber(currentWindow, frameKey)
+ props.tabId = tabId
return props
}
render () {
- if (!this.props.showSessionIcon) {
+ if (
+ this.props.isPinned ||
+ !this.props.showPartitionIcon ||
+ this.props.partitionNumber === 0
+ ) {
return null
}
- const newSession = StyleSheet.create({
- indicator: {
- // Based on getTextColorForBackground() icons can be only black or white.
- filter: this.props.isActive && this.props.iconColor === 'white' ? 'invert(100%)' : 'none'
+
+ const newSessionProps = StyleSheet.create({
+ newSession__indicator: {
+ filter: this.props.isActive && this.props.textIsWhite
+ ? 'invert(100%)'
+ : 'none'
}
})
return
}
@@ -73,21 +66,17 @@ class NewSessionIcon extends React.Component {
module.exports = ReduxComponent.connect(NewSessionIcon)
const styles = StyleSheet.create({
- icon: {
+ newSession__icon: {
+ zIndex: globalStyles.zindex.zindexWindow,
+ boxSizing: 'border-box',
+ display: 'flex',
+ alignItems: 'center',
+ backgroundImage: `url(${newSessionSvg})`,
+ backgroundPosition: 'center left',
+ backgroundRepeat: 'no-repeat',
+ backgroundSize: '13px',
width: globalStyles.spacing.iconSize,
- minWidth: globalStyles.spacing.iconSize,
height: globalStyles.spacing.iconSize,
- backgroundSize: globalStyles.spacing.iconSize,
- fontSize: globalStyles.fontSize.tabIcon,
- backgroundPosition: 'center',
- backgroundRepeat: 'no-repeat',
- paddingLeft: globalStyles.spacing.defaultIconPadding,
- paddingRight: globalStyles.spacing.defaultIconPadding
- },
-
- newSession: {
- position: 'relative',
- backgroundImage: `url(${newSessionSvg})`,
- backgroundPosition: 'left'
+ marginRight: globalStyles.spacing.defaultTabMargin
}
})
diff --git a/app/renderer/components/tabs/tab.js b/app/renderer/components/tabs/tab.js
index 5ccf1909af3..1fa497944ba 100644
--- a/app/renderer/components/tabs/tab.js
+++ b/app/renderer/components/tabs/tab.js
@@ -371,7 +371,7 @@ class Tab extends React.Component {
-
+
diff --git a/test/unit/app/renderer/components/tabs/content/newSessionIconTest.js b/test/unit/app/renderer/components/tabs/content/newSessionIconTest.js
index 7643642eb28..24470da8fdb 100644
--- a/test/unit/app/renderer/components/tabs/content/newSessionIconTest.js
+++ b/test/unit/app/renderer/components/tabs/content/newSessionIconTest.js
@@ -7,38 +7,39 @@ const mockery = require('mockery')
const {mount} = require('enzyme')
const assert = require('assert')
const Immutable = require('immutable')
-const {tabs} = require('../../../../../../../js/constants/config')
const fakeElectron = require('../../../../../lib/fakeElectron')
+const {intersection} = require('../../../../../../../app/renderer/components/styles/global')
require('../../../../../braveUnit')
const index = 0
const tabId = 1
const frameKey = 1
-const invalidFrameKey = 71
-const fakeAppStoreRenderer = {
- state: Immutable.fromJS({
- windows: [{
- windowId: 1,
- windowUUID: 'uuid'
- }],
- tabs: [{
- tabId: tabId,
- windowId: 1,
- windowUUID: 'uuid',
- url: 'https://brave.com'
- }]
- }),
- addChangeListener: () => {},
- removeChangeListener: () => {}
-}
+const fakeAppStoreRenderer = Immutable.fromJS({
+ windows: [{
+ windowId: 1,
+ windowUUID: 'uuid'
+ }],
+ tabs: [{
+ tabId: tabId,
+ windowId: 1,
+ windowUUID: 'uuid',
+ url: 'https://brave.com'
+ }],
+ tabsInternal: {
+ index: {
+ 1: 0
+ }
+ }
+})
const defaultWindowStore = Immutable.fromJS({
activeFrameKey: frameKey,
frames: [{
key: frameKey,
tabId: tabId,
- location: 'http://brave.com'
+ location: 'http://brave.com',
+ partitionNumber: 1
}],
tabs: [{
key: frameKey,
@@ -54,13 +55,13 @@ const defaultWindowStore = Immutable.fromJS({
},
ui: {
tabs: {
- hoverTabIndex: index
+ tabHoverState: 1
}
}
})
-describe.skip('Tabs content - NewSessionIcon', function () {
- let Tab, windowStore, NewSessionIcon
+describe('Tabs content - NewSessionIcon', function () {
+ let NewSessionIcon, windowStore, appStore
before(function () {
mockery.enable({
@@ -69,15 +70,11 @@ describe.skip('Tabs content - NewSessionIcon', function () {
useCleanCache: true
})
mockery.registerMock('electron', fakeElectron)
- mockery.registerMock('../../../js/stores/appStoreRenderer', fakeAppStoreRenderer)
- mockery.registerMock('../../../../extensions/brave/img/tabs/loading.svg')
mockery.registerMock('../../../../extensions/brave/img/tabs/new_session.svg')
- mockery.registerMock('../../../../extensions/brave/img/tabs/private.svg')
- mockery.registerMock('../../../../extensions/brave/img/tabs/close_btn_hover.svg')
- mockery.registerMock('../../../../extensions/brave/img/tabs/close_btn_normal.svg')
windowStore = require('../../../../../../../js/stores/windowStore')
- Tab = require('../../../../../../../app/renderer/components/tabs/tab')
- NewSessionIcon = require('../../../../../../../app/renderer/components/tabs/content/newSessionIcon')
+ appStore = require('../../../../../../../js/stores/appStoreRenderer')
+ NewSessionIcon = require('../../../../../../../app/renderer/components/tabs/content/NewSessionIcon')
+ appStore.state = fakeAppStoreRenderer
})
after(function () {
@@ -85,195 +82,63 @@ describe.skip('Tabs content - NewSessionIcon', function () {
mockery.disable()
})
- describe('should show', function () {
- it('icon if current tab is a new session tab', function () {
- windowStore.state = defaultWindowStore.merge({
- activeFrameKey: 0,
- frames: [{
- partitionNumber: 1,
- breakpoint: 'default'
- }],
- ui: {
- tabs: {
- hoverTabIndex: null
- }
- }
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 1)
- })
-
- it('icon if mouse is not over tab and breakpoint is default', function () {
- windowStore.state = defaultWindowStore.merge({
- activeFrameKey: 0,
- frames: [{
- partitionNumber: 1,
- breakpoint: 'default'
- }],
- ui: {
- tabs: {
- hoverTabIndex: null
- }
- }
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 1)
- })
-
- it('icon if mouse is not over tab and breakpoint is large', function () {
- windowStore.state = defaultWindowStore.merge({
- activeFrameKey: 0,
- frames: [{
- partitionNumber: 1,
- breakpoint: 'large'
- }],
- ui: {
- tabs: {
- hoverTabIndex: null
- }
- }
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 1)
- })
-
- it('icon if tab is not active and breakpoint is largeMedium', function () {
- windowStore.state = defaultWindowStore.merge({
- activeFrameKey: 0,
- frames: [{
- partitionNumber: 1,
- breakpoint: 'largeMedium'
- }],
- ui: {
- tabs: {
- hoverTabIndex: null
- }
- }
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 1)
- })
-
- it('partition number for new sessions', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 3,
- breakpoint: 'default'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('TabIcon').props().symbolContent, 3)
- })
-
- it('partition number for sessions with number set by opener (ex: clicking target=_blank)', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 'partition-3',
- breakpoint: 'default'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('TabIcon').props().symbolContent, 3)
+ describe('should show icon', function () {
+ it('if tab is not hovered', function * () {
+ windowStore.state = defaultWindowStore
+ .mergeIn(['ui', 'tabs'], {
+ intersectionRatio: intersection.noIntersection,
+ tabHoverIndex: 1337
+ })
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 1)
})
- it('max partition number even if session is bigger', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1000,
- breakpoint: 'default'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('TabIcon').props().symbolContent, tabs.maxAllowedNewSessions)
- })
- it('passing in a frame key which does not exist does not fail', function () {
+ it('if tab is not active and size is small', function * () {
windowStore.state = defaultWindowStore
- const wrapper = mount()
- assert(wrapper.find('TabIcon'))
+ .mergeIn(['ui', 'tabs'], {
+ tabHoverIndex: 1337,
+ intersectionRatio: intersection.at45
+ })
+ .set('activeFrameKey', 1337)
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 1)
})
})
describe('should not show icon', function () {
- it('if current tab is not private', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: false
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
- })
-
- it('if mouse is over tab and breakpoint is default', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: true,
- breakpoint: 'default'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
- })
-
- it('if mouse is over tab and breakpoint is large', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: true,
- breakpoint: 'large'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
- })
-
- it('if tab is active and breakpoint is largeMedium', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: true,
- breakpoint: 'largeMedium'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
- })
-
- it('if breakpoint is medium', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: false,
- breakpoint: 'medium'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
+ it('if tab is not partitioned', function * () {
+ windowStore.state = defaultWindowStore
+ .setIn(['frames', index, 'partitionNumber'], false)
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 0)
})
- it('if breakpoint is mediumSmall', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: false,
- breakpoint: 'mediumSmall'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
+ it('if tab is being hovered', function * () {
+ windowStore.state = defaultWindowStore
+ .setIn(['ui', 'tabs', 'hoverTabIndex'], index)
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 0)
})
- it('if breakpoint is small', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: true,
- breakpoint: 'small'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
+ it('if for active tab if size is small', function * () {
+ windowStore.state = defaultWindowStore
+ .setIn(['ui', 'tabs', 'intersectionRatio'], intersection.at45)
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 0)
})
- it('if breakpoint is extraSmall', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: true,
- breakpoint: 'extraSmall'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
+ it('if tab is being intersected at 35% or less', function * () {
+ windowStore.state = defaultWindowStore
+ .setIn(['ui', 'tabs', 'intersectionRatio'], intersection.at20)
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 0)
})
- it('if breakpoint is the smallest', function () {
- windowStore.state = defaultWindowStore.mergeIn(['frames', 0], {
- partitionNumber: 1,
- hoverState: true,
- breakpoint: 'smallest'
- })
- const wrapper = mount()
- assert.equal(wrapper.find('NewSessionIcon').length, 0)
+ it('if partitionNumber is zero', function * () {
+ windowStore.state = defaultWindowStore
+ .setIn(['frames', index, 'partitionNumber'], 0)
+ const wrapper = mount()
+ assert.equal(wrapper.find('TabIcon').length, 0)
})
})
})