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' )
@@ -119,10 +121,17 @@ class Tab extends React.Component {
119
121
}
120
122
121
123
onDragStart ( e ) {
124
+ // showing up the sentinel while dragging leads to show the shadow
125
+ // of the next tab. See 10691#issuecomment-329854096
126
+ // this is added back when dragEnd event happens
127
+ this . tabSentinel . style . display = 'none'
128
+
122
129
dnd . onDragStart ( dragTypes . TAB , this . frame , e )
123
130
}
124
131
125
132
onDragEnd ( e ) {
133
+ // re-enable the tabSentinel after drag ends
134
+ this . tabSentinel . style . display = 'block'
126
135
dnd . onDragEnd ( dragTypes . TAB , this . frame , e )
127
136
}
128
137
@@ -186,9 +195,11 @@ class Tab extends React.Component {
186
195
}
187
196
188
197
componentDidMount ( ) {
189
- // do not observe pinned tabs
198
+ // unobserve tabs that we don't need. This will
199
+ // likely be made by onObserve method but added again as
200
+ // just to double-check
190
201
if ( this . props . isPinned ) {
191
- this . observer . unobserve ( this . tabSentinel )
202
+ this . observer && this . observer . unobserve ( this . tabSentinel )
192
203
}
193
204
const threshold = Object . values ( globalStyles . intersection )
194
205
// At this moment Chrome can't handle unitless zeroes for rootMargin
@@ -200,20 +211,11 @@ class Tab extends React.Component {
200
211
this . tabNode . addEventListener ( 'auxclick' , this . onAuxClick . bind ( this ) )
201
212
}
202
213
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
214
componentWillUnmount ( ) {
212
215
this . observer . unobserve ( this . tabSentinel )
213
216
}
214
217
215
218
onObserve ( entries ) {
216
- // avoid observing pinned tabs
217
219
if ( this . props . isPinnedTab ) {
218
220
return
219
221
}
@@ -234,27 +236,32 @@ class Tab extends React.Component {
234
236
mergeProps ( state , ownProps ) {
235
237
const currentWindow = state . get ( 'currentWindow' )
236
238
const frame = frameStateUtil . getFrameByKey ( currentWindow , ownProps . frameKey ) || Immutable . Map ( )
239
+ const frameKey = ownProps . frameKey
240
+ const tabId = frame . get ( 'tabId' , tabState . TAB_ID_NONE )
241
+ const isPinned = tabState . isTabPinned ( state , tabId )
242
+ const partOfFullPageSet = ownProps . partOfFullPageSet
243
+
244
+ // TODO: this should have its own method
237
245
const notifications = state . get ( 'notifications' )
238
246
const notificationOrigins = notifications ? notifications . map ( bar => bar . get ( 'frameOrigin' ) ) : false
239
247
const notificationBarActive = frame . get ( 'location' ) && notificationOrigins &&
240
248
notificationOrigins . includes ( UrlUtil . getUrlOrigin ( frame . get ( 'location' ) ) )
241
- const tabId = frame . get ( 'tabId' , tabState . TAB_ID_NONE )
242
249
243
250
const props = { }
244
- // used in renderer
245
- props . frameKey = ownProps . frameKey
246
- props . isPrivateTab = frame . get ( 'isPrivate' )
251
+ // TODO: this should have its own method
247
252
props . notificationBarActive = notificationBarActive
248
- props . isActive = frameStateUtil . isFrameKeyActive ( currentWindow , props . frameKey )
253
+ props . frameKey = frameKey
254
+ props . isPinnedTab = isPinned
255
+ props . isPrivateTab = privateState . isPrivateTab ( currentWindow , frameKey )
256
+ props . isActive = frameStateUtil . isFrameKeyActive ( currentWindow , frameKey )
249
257
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 )
258
+ props . themeColor = tabUIState . getThemeColor ( currentWindow , frameKey )
253
259
props . title = frame . get ( 'title' )
254
- props . partOfFullPageSet = ownProps . partOfFullPageSet
260
+ props . partOfFullPageSet = partOfFullPageSet
261
+ props . showAudioTopBorder = audioState . showAudioTopBorder ( currentWindow , frameKey , isPinned )
262
+ props . centralizeTabIcons = tabUIState . centralizeTabIcons ( currentWindow , frameKey , isPinned )
255
263
256
264
// used in other functions
257
- props . totalTabs = state . get ( 'tabs' ) . size
258
265
props . dragData = state . getIn ( [ 'dragData' , 'type' ] ) === dragTypes . TAB && state . get ( 'dragData' )
259
266
props . tabId = tabId
260
267
props . previewMode = currentWindow . getIn ( [ 'ui' , 'tabs' , 'previewMode' ] )
@@ -265,7 +272,7 @@ class Tab extends React.Component {
265
272
render ( ) {
266
273
// we don't want themeColor if tab is private
267
274
const perPageStyles = ! this . props . isPrivateTab && StyleSheet . create ( {
268
- themeColor : {
275
+ tab_themeColor : {
269
276
color : this . props . themeColor ? getTextColorForBackground ( this . props . themeColor ) : 'inherit' ,
270
277
background : this . props . themeColor ? this . props . themeColor : 'inherit' ,
271
278
':hover' : {
@@ -301,13 +308,15 @@ class Tab extends React.Component {
301
308
className = { css (
302
309
styles . tab ,
303
310
// 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 ,
311
+ isWindows && styles . tab_forWindows ,
312
+ this . props . isPinnedTab && styles . tab_pinned ,
313
+ this . props . isActive && styles . tab_active ,
314
+ this . props . showAudioTopBorder && styles . tab_audioTopBorder ,
315
+ this . props . isActive && this . props . themeColor && perPageStyles . tab_themeColor ,
308
316
// Private color should override themeColor
309
- this . props . isPrivateTab && styles . private ,
310
- this . props . isActive && this . props . isPrivateTab && styles . activePrivateTab
317
+ this . props . isPrivateTab && styles . tab_private ,
318
+ this . props . isActive && this . props . isPrivateTab && styles . tab_active_private ,
319
+ this . props . centralizeTabIcons && styles . tab__content_centered
311
320
) }
312
321
data-test-id = 'tab'
313
322
data-frame-key = { this . props . frameKey }
@@ -323,7 +332,10 @@ class Tab extends React.Component {
323
332
ref = { ( node ) => { this . tabSentinel = node } }
324
333
className = { css ( styles . tab__sentinel ) }
325
334
/>
326
- < div className = { css ( styles . tabId ) } >
335
+ < div className = { css (
336
+ styles . tab__identity ,
337
+ this . props . centralizeTabIcons && styles . tab__content_centered
338
+ ) } >
327
339
< Favicon tabId = { this . props . tabId } />
328
340
< AudioTabIcon tabId = { this . props . tabId } />
329
341
< TabTitle tabId = { this . props . tabId } />
@@ -337,34 +349,39 @@ class Tab extends React.Component {
337
349
}
338
350
339
351
const styles = StyleSheet . create ( {
340
- // Windows specific style
341
- tabForWindows : {
342
- color : '#555'
343
- } ,
344
-
345
352
tab : {
346
353
borderWidth : '0 1px 0 0' ,
347
354
borderStyle : 'solid' ,
348
355
borderColor : '#bbb' ,
349
356
boxSizing : 'border-box' ,
350
- color : '#5a5a5a' ,
357
+ color : theme . tab . color ,
351
358
display : 'flex' ,
352
359
marginTop : '0' ,
353
- transition : `transform 200ms ease, ${ globalStyles . transition . tabBackgroundTransition } ` ,
360
+ transition : theme . tab . transition ,
354
361
left : '0' ,
355
362
opacity : '1' ,
356
- width : '100%' ,
363
+ height : '-webkit-fill-available' ,
364
+ width : '-webkit-fill-available' ,
357
365
alignItems : 'center' ,
358
366
justifyContent : 'space-between' ,
359
- padding : globalStyles . spacing . defaultTabPadding ,
367
+ padding : 0 ,
360
368
position : 'relative' ,
361
369
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' ,
370
+ ':hover' : {
371
+ background : theme . tab . hover . background
372
+ }
373
+ } ,
374
+
375
+ // Windows specific style
376
+ tab_forWindows : {
377
+ color : theme . tab . forWindows . color
378
+ } ,
379
+
380
+ tab_active : {
381
+ background : theme . tab . active . background ,
365
382
366
383
':hover' : {
367
- background : 'linear-gradient(to bottom, rgba(255, 255, 255, 0.8), rgba(250, 250, 250, 0.4))'
384
+ background : theme . tab . active . background
368
385
}
369
386
} ,
370
387
@@ -380,59 +397,56 @@ const styles = StyleSheet.create({
380
397
width : globalStyles . spacing . sentinelSize
381
398
} ,
382
399
383
- tabId : {
384
- justifyContent : 'center' ,
400
+ tab_audioTopBorder : {
401
+ '::before' : {
402
+ content : `''` ,
403
+ display : 'block' ,
404
+ position : 'absolute' ,
405
+ top : 0 ,
406
+ left : 0 ,
407
+ right : 0 ,
408
+ height : '2px' ,
409
+ background : 'lightskyblue'
410
+ }
411
+ } ,
412
+
413
+ tab__identity : {
414
+ justifyContent : 'flex-start' ,
385
415
alignItems : 'center' ,
386
416
display : 'flex' ,
387
417
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'
418
+ minWidth : '0' , // @see https://bugzilla.mozilla.org/show_bug.cgi?id=1108514#c5
419
+ marginLeft : globalStyles . spacing . defaultTabMargin
394
420
} ,
395
421
396
- isPinned : {
422
+ tab__content_centered : {
423
+ justifyContent : 'center' ,
424
+ flex : 'auto' ,
397
425
padding : 0 ,
398
- width : `calc(${ globalStyles . spacing . tabsToolbarHeight } * 1.1)` ,
399
- justifyContent : 'center'
426
+ margin : 0
400
427
} ,
401
428
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
- }
429
+ tab_pinned : {
430
+ padding : 0 ,
431
+ width : '28px' ,
432
+ justifyContent : 'center'
413
433
} ,
414
434
415
- activePrivateTab : {
416
- background : globalStyles . color . privateTabBackgroundActive ,
435
+ tab_active_private : {
436
+ background : theme . tab . active . private . background ,
437
+ color : theme . tab . active . private . color ,
417
438
418
439
':hover' : {
419
- background : globalStyles . color . privateTabBackgroundActive
440
+ background : theme . tab . active . private . background
420
441
}
421
442
} ,
422
443
423
- private : {
424
- background : 'rgba(75, 60, 110, 0.2)' ,
444
+ tab_private : {
445
+ background : theme . tab . private . background ,
425
446
426
447
':hover' : {
427
- background : globalStyles . color . privateTabBackgroundActive
428
- }
429
- } ,
430
-
431
- dragging : {
432
- ':hover' : {
433
- closeTab : {
434
- opacity : '0'
435
- }
448
+ color : theme . tab . active . private . color ,
449
+ background : theme . tab . active . private . background
436
450
}
437
451
}
438
452
} )
0 commit comments