1
1
/* This Source Code Form is subject to the terms of the Mozilla Public
2
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
2
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
4
5
5
const React = require ( 'react' )
6
- const { StyleSheet, css} = require ( 'aphrodite' )
6
+ const { StyleSheet, css} = require ( 'aphrodite/no-important ' )
7
7
const Immutable = require ( 'immutable' )
8
8
9
9
// Components
@@ -23,7 +23,8 @@ const windowActions = require('../../../../js/actions/windowActions')
23
23
// Store
24
24
const windowStore = require ( '../../../../js/stores/windowStore' )
25
25
26
- // State
26
+ // State helpers
27
+ const privateState = require ( '../../../common/state/tabContentState/privateState' )
27
28
const audioState = require ( '../../../common/state/tabContentState/audioState' )
28
29
const tabUIState = require ( '../../../common/state/tabUIState' )
29
30
const tabState = require ( '../../../common/state/tabState' )
@@ -33,6 +34,7 @@ const dragTypes = require('../../../../js/constants/dragTypes')
33
34
34
35
// Styles
35
36
const globalStyles = require ( '../styles/global' )
37
+ const { theme} = require ( '../styles/theme' )
36
38
37
39
// Utils
38
40
const cx = require ( '../../../../js/lib/classSet' )
@@ -186,9 +188,11 @@ class Tab extends React.Component {
186
188
}
187
189
188
190
componentDidMount ( ) {
189
- // do not observe pinned tabs
191
+ // unobserve tabs that we don't need. This will
192
+ // likely be made by onObserve method but added again as
193
+ // just to double-check
190
194
if ( this . props . isPinned ) {
191
- this . observer . unobserve ( this . tabSentinel )
195
+ this . observer && this . observer . unobserve ( this . tabSentinel )
192
196
}
193
197
const threshold = Object . values ( globalStyles . intersection )
194
198
// At this moment Chrome can't handle unitless zeroes for rootMargin
@@ -200,20 +204,11 @@ class Tab extends React.Component {
200
204
this . tabNode . addEventListener ( 'auxclick' , this . onAuxClick . bind ( this ) )
201
205
}
202
206
203
- componentDidUpdate ( ) {
204
- // if a tab was just pinned, unobserve its intersection
205
- // this gives us some more performance boost
206
- if ( this . props . isPinnedTab ) {
207
- this . observer . unobserve ( this . tabSentinel )
208
- }
209
- }
210
-
211
207
componentWillUnmount ( ) {
212
208
this . observer . unobserve ( this . tabSentinel )
213
209
}
214
210
215
211
onObserve ( entries ) {
216
- // avoid observing pinned tabs
217
212
if ( this . props . isPinnedTab ) {
218
213
return
219
214
}
@@ -234,27 +229,32 @@ class Tab extends React.Component {
234
229
mergeProps ( state , ownProps ) {
235
230
const currentWindow = state . get ( 'currentWindow' )
236
231
const frame = frameStateUtil . getFrameByKey ( currentWindow , ownProps . frameKey ) || Immutable . Map ( )
232
+ const frameKey = ownProps . frameKey
233
+ const tabId = frame . get ( 'tabId' , tabState . TAB_ID_NONE )
234
+ const isPinned = tabState . isTabPinned ( state , tabId )
235
+ const partOfFullPageSet = ownProps . partOfFullPageSet
236
+
237
+ // TODO: this should have its own method
237
238
const notifications = state . get ( 'notifications' )
238
239
const notificationOrigins = notifications ? notifications . map ( bar => bar . get ( 'frameOrigin' ) ) : false
239
240
const notificationBarActive = frame . get ( 'location' ) && notificationOrigins &&
240
241
notificationOrigins . includes ( UrlUtil . getUrlOrigin ( frame . get ( 'location' ) ) )
241
- const tabId = frame . get ( 'tabId' , tabState . TAB_ID_NONE )
242
242
243
243
const props = { }
244
- // used in renderer
245
- props . frameKey = ownProps . frameKey
246
- props . isPrivateTab = frame . get ( 'isPrivate' )
244
+ // TODO: this should have its own method
247
245
props . notificationBarActive = notificationBarActive
248
- props . isActive = frameStateUtil . isFrameKeyActive ( currentWindow , props . frameKey )
246
+ props . frameKey = frameKey
247
+ props . isPinnedTab = isPinned
248
+ props . isPrivateTab = privateState . isPrivateTab ( currentWindow , frameKey )
249
+ props . isActive = frameStateUtil . isFrameKeyActive ( currentWindow , frameKey )
249
250
props . tabWidth = currentWindow . getIn ( [ 'ui' , 'tabs' , 'fixTabWidth' ] )
250
- props . isPinnedTab = tabState . isTabPinned ( state , tabId )
251
- props . canPlayAudio = audioState . canPlayAudio ( currentWindow , props . frameKey )
252
- props . themeColor = tabUIState . getThemeColor ( currentWindow , props . frameKey )
251
+ props . themeColor = tabUIState . getThemeColor ( currentWindow , frameKey )
253
252
props . title = frame . get ( 'title' )
254
- props . partOfFullPageSet = ownProps . partOfFullPageSet
253
+ props . partOfFullPageSet = partOfFullPageSet
254
+ props . showAudioTopBorder = audioState . showAudioTopBorder ( currentWindow , frameKey , isPinned )
255
+ props . centralizeTabIcons = tabUIState . centralizeTabIcons ( currentWindow , frameKey , isPinned )
255
256
256
257
// used in other functions
257
- props . totalTabs = state . get ( 'tabs' ) . size
258
258
props . dragData = state . getIn ( [ 'dragData' , 'type' ] ) === dragTypes . TAB && state . get ( 'dragData' )
259
259
props . tabId = tabId
260
260
props . previewMode = currentWindow . getIn ( [ 'ui' , 'tabs' , 'previewMode' ] )
@@ -265,7 +265,7 @@ class Tab extends React.Component {
265
265
render ( ) {
266
266
// we don't want themeColor if tab is private
267
267
const perPageStyles = ! this . props . isPrivateTab && StyleSheet . create ( {
268
- themeColor : {
268
+ tab_themeColor : {
269
269
color : this . props . themeColor ? getTextColorForBackground ( this . props . themeColor ) : 'inherit' ,
270
270
background : this . props . themeColor ? this . props . themeColor : 'inherit' ,
271
271
':hover' : {
@@ -301,13 +301,15 @@ class Tab extends React.Component {
301
301
className = { css (
302
302
styles . tab ,
303
303
// Windows specific style
304
- isWindows && styles . tabForWindows ,
305
- this . props . isPinnedTab && styles . isPinned ,
306
- this . props . isActive && styles . active ,
307
- this . props . isActive && this . props . themeColor && perPageStyles . themeColor ,
304
+ isWindows && styles . tab_forWindows ,
305
+ this . props . isPinnedTab && styles . tab_pinned ,
306
+ this . props . isActive && styles . tab_active ,
307
+ this . props . showAudioTopBorder && styles . tab_audioTopBorder ,
308
+ this . props . isActive && this . props . themeColor && perPageStyles . tab_themeColor ,
308
309
// Private color should override themeColor
309
- this . props . isPrivateTab && styles . private ,
310
- this . props . isActive && this . props . isPrivateTab && styles . activePrivateTab
310
+ this . props . isPrivateTab && styles . tab_private ,
311
+ this . props . isActive && this . props . isPrivateTab && styles . tab_active_private ,
312
+ this . props . centralizeTabIcons && styles . tab__content_centered
311
313
) }
312
314
data-test-id = 'tab'
313
315
data-frame-key = { this . props . frameKey }
@@ -323,7 +325,10 @@ class Tab extends React.Component {
323
325
ref = { ( node ) => { this . tabSentinel = node } }
324
326
className = { css ( styles . tab__sentinel ) }
325
327
/>
326
- < div className = { css ( styles . tabId ) } >
328
+ < div className = { css (
329
+ styles . tab__identity ,
330
+ this . props . centralizeTabIcons && styles . tab__content_centered
331
+ ) } >
327
332
< Favicon tabId = { this . props . tabId } />
328
333
< AudioTabIcon tabId = { this . props . tabId } />
329
334
< TabTitle tabId = { this . props . tabId } />
@@ -337,34 +342,39 @@ class Tab extends React.Component {
337
342
}
338
343
339
344
const styles = StyleSheet . create ( {
340
- // Windows specific style
341
- tabForWindows : {
342
- color : '#555'
343
- } ,
344
-
345
345
tab : {
346
346
borderWidth : '0 1px 0 0' ,
347
347
borderStyle : 'solid' ,
348
348
borderColor : '#bbb' ,
349
349
boxSizing : 'border-box' ,
350
- color : '#5a5a5a' ,
350
+ color : theme . tab . color ,
351
351
display : 'flex' ,
352
352
marginTop : '0' ,
353
- transition : `transform 200ms ease, ${ globalStyles . transition . tabBackgroundTransition } ` ,
353
+ transition : theme . tab . transition ,
354
354
left : '0' ,
355
355
opacity : '1' ,
356
- width : '100%' ,
356
+ height : '-webkit-fill-available' ,
357
+ width : '-webkit-fill-available' ,
357
358
alignItems : 'center' ,
358
359
justifyContent : 'space-between' ,
359
- padding : globalStyles . spacing . defaultTabPadding ,
360
+ padding : 0 ,
360
361
position : 'relative' ,
361
362
362
- // globalStyles.spacing.tabHeight has been set to globalStyles.spacing.tabsToolbarHeight,
363
- // which is 1px extra due to the border-top of .tabsToolbar
364
- height : '-webkit-fill-available' ,
363
+ ':hover' : {
364
+ background : theme . tab . hover . background
365
+ }
366
+ } ,
367
+
368
+ // Windows specific style
369
+ tab_forWindows : {
370
+ color : theme . tab . forWindows . color
371
+ } ,
372
+
373
+ tab_active : {
374
+ background : theme . tab . active . background ,
365
375
366
376
':hover' : {
367
- background : 'linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(250, 250, 250, 0.4))'
377
+ background : theme . tab . active . background
368
378
}
369
379
} ,
370
380
@@ -380,59 +390,56 @@ const styles = StyleSheet.create({
380
390
width : globalStyles . spacing . sentinelSize
381
391
} ,
382
392
383
- tabId : {
384
- justifyContent : 'center' ,
393
+ tab_audioTopBorder : {
394
+ '::before' : {
395
+ content : `''` ,
396
+ display : 'block' ,
397
+ position : 'absolute' ,
398
+ top : 0 ,
399
+ left : 0 ,
400
+ right : 0 ,
401
+ height : '2px' ,
402
+ background : 'lightskyblue'
403
+ }
404
+ } ,
405
+
406
+ tab__identity : {
407
+ justifyContent : 'flex-start' ,
385
408
alignItems : 'center' ,
386
409
display : 'flex' ,
387
410
flex : '1' ,
388
-
389
- // @see https://bugzilla.mozilla.org/show_bug.cgi?id=1108514#c5
390
- minWidth : '0' ,
391
-
392
- // prevent the icons wrapper from being the target of mouse events.
393
- pointerEvents : 'none'
411
+ minWidth : '0' , // @see https://bugzilla.mozilla.org/show_bug.cgi?id=1108514#c5
412
+ marginLeft : globalStyles . spacing . defaultTabMargin
394
413
} ,
395
414
396
- isPinned : {
415
+ tab__content_centered : {
416
+ justifyContent : 'center' ,
417
+ flex : 'auto' ,
397
418
padding : 0 ,
398
- width : `calc(${ globalStyles . spacing . tabsToolbarHeight } * 1.1)` ,
399
- justifyContent : 'center'
419
+ margin : 0
400
420
} ,
401
421
402
- active : {
403
- background : `rgba(255, 255, 255, 1.0)` ,
404
- marginTop : '0' ,
405
- borderWidth : '0 1px 0 0' ,
406
- borderStyle : 'solid' ,
407
- borderColor : '#bbb' ,
408
- color : '#000' ,
409
-
410
- ':hover' : {
411
- background : `linear-gradient(to bottom, #fff, ${ globalStyles . color . chromePrimary } )`
412
- }
422
+ tab_pinned : {
423
+ padding : 0 ,
424
+ width : '28px' ,
425
+ justifyContent : 'center'
413
426
} ,
414
427
415
- activePrivateTab : {
416
- background : globalStyles . color . privateTabBackgroundActive ,
428
+ tab_active_private : {
429
+ background : theme . tab . active . private . background ,
430
+ color : theme . tab . active . private . color ,
417
431
418
432
':hover' : {
419
- background : globalStyles . color . privateTabBackgroundActive
433
+ background : theme . tab . active . private . background
420
434
}
421
435
} ,
422
436
423
- private : {
424
- background : 'rgba(75, 60, 110, 0.2)' ,
437
+ tab_private : {
438
+ background : theme . tab . private . background ,
425
439
426
440
':hover' : {
427
- background : globalStyles . color . privateTabBackgroundActive
428
- }
429
- } ,
430
-
431
- dragging : {
432
- ':hover' : {
433
- closeTab : {
434
- opacity : '0'
435
- }
441
+ color : theme . tab . active . private . color ,
442
+ background : theme . tab . active . private . background
436
443
}
437
444
}
438
445
} )
0 commit comments