<commit_before>/* 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/. */

const React = require('react')
const ImmutableComponent = require('../../../js/components/immutableComponent')
const {StyleSheet, css} = require('aphrodite/no-important')
const globalStyles = require('./styles/global')
const {isWindows} = require('../../common/lib/platformUtil')
const {getTextColorForBackground} = require('../../../js/lib/color')
const {tabs} = require('../../../js/constants/config')

const newSessionSvg = require('../../extensions/brave/img/tabs/new_session.svg')

/**
 * Boilerplate component for all tab icons
 */
class TabIcon extends ImmutableComponent {
  render () {
    const tabIconStyle = {
      // Currently it's not possible to concatenate Aphrodite generated classes
      // and pre-built classes using default Aphrodite API, so we keep with inline-style
      fontSize: this.props.symbolContent ? '8px' : 'inherit',
      display: 'flex',
      alignSelf: 'center',
      width: globalStyles.spacing.iconSize,
      height: globalStyles.spacing.iconSize,
      alignItems: 'center',
      justifyContent: this.props.symbolContent ? 'flex-end' : 'center',
      fontWeight: this.props.symbolContent ? 'bold' : 'normal',
      color: this.props.symbolContent ? globalStyles.color.black100 : 'inherit'
    }
    return <div
      className={this.props.className}
      data-test-favicon={this.props['data-test-favicon']}
      onClick={this.props.onClick}>
      {
      this.props.symbol
        ? <span
          className={this.props.symbol}
          data-test-id={this.props['data-test-id']}
          data-l10n-id={this.props.l10nId}
          data-l10n-args={JSON.stringify(this.props.l10nArgs || {})}
          style={tabIconStyle}>{this.props.symbolContent}</span>
        : null
      }
    </div>
  }
}

class Favicon extends ImmutableComponent {
  get favicon () {
    return !this.props.isLoading && this.props.tabProps.get('icon')
  }

  get loadingIcon () {
    return this.props.isLoading
      ? globalStyles.appIcons.loading
      : null
  }

  get defaultIcon () {
    return (!this.props.isLoading && !this.favicon)
      ? globalStyles.appIcons.defaultIcon
      : null
  }

  get narrowView () {
    return this.props.tabProps.get('breakpoint') === 'smallest'
  }

  render () {
    const iconStyles = StyleSheet.create({
      favicon: {backgroundImage: `url(${this.favicon})`}
    })
    return this.props.tabProps.get('location') !== 'about:newtab'
      ? <TabIcon
        data-test-favicon={this.favicon}
        data-test-id={this.loadingIcon ? 'loading' : 'defaultIcon'}
        className={css(
          styles.icon,
          this.favicon && iconStyles.favicon,
          !this.props.tabProps.get('pinnedLocation') && this.narrowView && styles.faviconNarrowView
        )}
        symbol={this.loadingIcon || this.defaultIcon} />
      : null
  }
}

class AudioTabIcon extends ImmutableComponent {
  get pageCanPlayAudio () {
    return this.props.tabProps.get('audioPlaybackActive') || this.props.tabProps.get('audioMuted')
  }

  get mediumView () {
    const sizes = ['large', 'largeMedium']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  get narrowView () {
    const sizes = ['medium', 'mediumSmall', 'small', 'extraSmall', 'smallest']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  get locationHasSecondaryIcon () {
    return !!this.props.tabProps.get('isPrivate') || !!this.props.tabProps.get('partitionNumber')
  }

  get mutedState () {
    return this.pageCanPlayAudio && this.props.tabProps.get('audioMuted')
  }

  get unmutedState () {
    this.props.tabProps.get('audioPlaybackActive') && !this.props.tabProps.get('audioMuted')
  }

  get audioIcon () {
    return !this.mutedState
      ? globalStyles.appIcons.volumeOn
      : globalStyles.appIcons.volumeOff
  }

  render () {
    return this.pageCanPlayAudio && !this.mediumView && !this.narrowView
      ? <TabIcon className={css(styles.icon, styles.audioIcon)} symbol={this.audioIcon} onClick={this.props.onClick} />
      : null
  }
}

class PrivateIcon extends ImmutableComponent {
  get narrowView () {
    const sizes = ['small', 'extraSmall', 'smallest']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  render () {
    return this.props.tabProps.get('isPrivate') && !this.props.tabProps.get('hoverState') && !this.narrowView
      ? <TabIcon className={css(styles.icon)} symbol={globalStyles.appIcons.private} />
      : null
  }
}

class NewSessionIcon extends ImmutableComponent {
  get narrowView () {
    const sizes = ['small', 'extraSmall', 'smallest']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  get partitionNumber () {
    return this.props.tabProps.get('partitionNumber')
  }

  get partitionIndicator () {
    // For now due to UI limitations set session up to 9 visually
    return this.partitionNumber > tabs.maxAllowedNewSessions
      ? tabs.maxAllowedNewSessions
      : this.partitionNumber
  }

  get iconColor () {
    const themeColor = this.props.tabProps.get('themeColor') || this.props.tabProps.get('computedThemeColor')
    return this.props.paintTabs && themeColor
      ? getTextColorForBackground(themeColor)
      : globalStyles.color.black100
  }

  render () {
    const newSession = StyleSheet.create({
      indicator: {
        // Based on getTextColorForBackground() icons can be only black or white.
        filter: this.props.isActive && this.iconColor === 'white' ? 'invert(100%)' : 'none'
      }
    })

    return this.partitionNumber && !this.props.tabProps.get('hoverState') && !this.narrowView
      ? <TabIcon symbol
        data-test-id='newSessionIcon'
        className={css(styles.icon, styles.newSession, newSession.indicator)}
        symbolContent={this.partitionIndicator}
        {...this.props} /><commit_msg>Remove string from tab on persistent partition<commit_after>/* 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/. */

const React = require('react')
const ImmutableComponent = require('../../../js/components/immutableComponent')
const {StyleSheet, css} = require('aphrodite/no-important')
const globalStyles = require('./styles/global')
const {isWindows} = require('../../common/lib/platformUtil')
const {getTextColorForBackground} = require('../../../js/lib/color')
const {tabs} = require('../../../js/constants/config')

const newSessionSvg = require('../../extensions/brave/img/tabs/new_session.svg')

/**
 * Boilerplate component for all tab icons
 */
class TabIcon extends ImmutableComponent {
  render () {
    const tabIconStyle = {
      // Currently it's not possible to concatenate Aphrodite generated classes
      // and pre-built classes using default Aphrodite API, so we keep with inline-style
      fontSize: this.props.symbolContent ? '8px' : 'inherit',
      display: 'flex',
      alignSelf: 'center',
      width: globalStyles.spacing.iconSize,
      height: globalStyles.spacing.iconSize,
      alignItems: 'center',
      justifyContent: this.props.symbolContent ? 'flex-end' : 'center',
      fontWeight: this.props.symbolContent ? 'bold' : 'normal',
      color: this.props.symbolContent ? globalStyles.color.black100 : 'inherit'
    }
    return <div
      className={this.props.className}
      data-test-favicon={this.props['data-test-favicon']}
      onClick={this.props.onClick}>
      {
      this.props.symbol
        ? <span
          className={this.props.symbol}
          data-test-id={this.props['data-test-id']}
          data-l10n-id={this.props.l10nId}
          data-l10n-args={JSON.stringify(this.props.l10nArgs || {})}
          style={tabIconStyle}>{this.props.symbolContent}</span>
        : null
      }
    </div>
  }
}

class Favicon extends ImmutableComponent {
  get favicon () {
    return !this.props.isLoading && this.props.tabProps.get('icon')
  }

  get loadingIcon () {
    return this.props.isLoading
      ? globalStyles.appIcons.loading
      : null
  }

  get defaultIcon () {
    return (!this.props.isLoading && !this.favicon)
      ? globalStyles.appIcons.defaultIcon
      : null
  }

  get narrowView () {
    return this.props.tabProps.get('breakpoint') === 'smallest'
  }

  render () {
    const iconStyles = StyleSheet.create({
      favicon: {backgroundImage: `url(${this.favicon})`}
    })
    return this.props.tabProps.get('location') !== 'about:newtab'
      ? <TabIcon
        data-test-favicon={this.favicon}
        data-test-id={this.loadingIcon ? 'loading' : 'defaultIcon'}
        className={css(
          styles.icon,
          this.favicon && iconStyles.favicon,
          !this.props.tabProps.get('pinnedLocation') && this.narrowView && styles.faviconNarrowView
        )}
        symbol={this.loadingIcon || this.defaultIcon} />
      : null
  }
}

class AudioTabIcon extends ImmutableComponent {
  get pageCanPlayAudio () {
    return this.props.tabProps.get('audioPlaybackActive') || this.props.tabProps.get('audioMuted')
  }

  get mediumView () {
    const sizes = ['large', 'largeMedium']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  get narrowView () {
    const sizes = ['medium', 'mediumSmall', 'small', 'extraSmall', 'smallest']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  get locationHasSecondaryIcon () {
    return !!this.props.tabProps.get('isPrivate') || !!this.props.tabProps.get('partitionNumber')
  }

  get mutedState () {
    return this.pageCanPlayAudio && this.props.tabProps.get('audioMuted')
  }

  get unmutedState () {
    this.props.tabProps.get('audioPlaybackActive') && !this.props.tabProps.get('audioMuted')
  }

  get audioIcon () {
    return !this.mutedState
      ? globalStyles.appIcons.volumeOn
      : globalStyles.appIcons.volumeOff
  }

  render () {
    return this.pageCanPlayAudio && !this.mediumView && !this.narrowView
      ? <TabIcon className={css(styles.icon, styles.audioIcon)} symbol={this.audioIcon} onClick={this.props.onClick} />
      : null
  }
}

class PrivateIcon extends ImmutableComponent {
  get narrowView () {
    const sizes = ['small', 'extraSmall', 'smallest']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  render () {
    return this.props.tabProps.get('isPrivate') && !this.props.tabProps.get('hoverState') && !this.narrowView
      ? <TabIcon className={css(styles.icon)} symbol={globalStyles.appIcons.private} />
      : null
  }
}

class NewSessionIcon extends ImmutableComponent {
  get narrowView () {
    const sizes = ['small', 'extraSmall', 'smallest']
    return sizes.includes(this.props.tabProps.get('breakpoint'))
  }

  get partitionNumber () {
    let partition = this.props.tabProps.get('partitionNumber')
    // Persistent partitions opened by `target="_blank"` will have
    // *partition-* string first, which causes bad UI. We don't need it for tabs
    if (typeof partition === 'string') {
      partition = partition.replace('partition-', '')
    }
    return partition
  }

  get partitionIndicator () {
    // For now due to UI limitations set session up to 9 visually
    return this.partitionNumber > tabs.maxAllowedNewSessions
      ? tabs.maxAllowedNewSessions
      : this.partitionNumber
  }

  get iconColor () {
    const themeColor = this.props.tabProps.get('themeColor') || this.props.tabProps.get('computedThemeColor')
    return this.props.paintTabs && themeColor
      ? getTextColorForBackground(themeColor)
      : globalStyles.color.black100
  }

  render () {
    const newSession = StyleSheet.create({
      indicator: {
        // Based on getTextColorForBackground() icons can be only black or white.
        filter: this.props.isActive && this.iconColor === 'white' ? 'invert(100%)' : 'none'
      }
    })

    return this.partitionNumber && !this.props.tabProps.get('hoverState') && !this.narrowView
      ? <TabIcon symbol
        data-test-id='newSessionIcon'
        className={css(styles.icon, styles.newSession, newSession.indicator)}
        symbolContent={this.partitionIndicator}
        {...this.props} />
{'fraction_non_alphanumeric': 0.1415979298075368, 'fraction_numerical': 0.0037198770823224972, 'mean_word_length': 3.2036029911624744, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1993533', 'n_tokens_mistral': 3799, 'n_tokens_neox': 3725, 'n_words': 729}