<commit_before>import React, { PureComponent } from 'react'
import {
  StyleSheet,
  Dimensions,
  View,
} from 'react-native'
import PropTypes from 'prop-types'

import ViewPager from './ViewPager'

const VIEWPORT_WIDTH = Dimensions.get('window').width

class TabbedPager extends PureComponent {

  static propTypes = {
    data: PropTypes.arrayOf(
      PropTypes.object
    ),
    dev: PropTypes.bool,
    lazyrender: PropTypes.bool,
    renderAsCarousel: PropTypes.bool,
    experimentalMirroring: PropTypes.bool,
    fullScreen: PropTypes.bool,
    forceRerenderOnPageChange: PropTypes.bool,
    initialPage: PropTypes.object,

    tabContainerPosition: PropTypes.string,
    scrollTabsEnabled: PropTypes.bool,
    staticTabWidth: PropTypes.number,
    showTabIndicator: PropTypes.bool,
    tabIndicatorColor: PropTypes.string,
    tabIndicatorHeight: PropTypes.number,

    DividerComponent: PropTypes.any,

    renderPage: PropTypes.func.isRequired,
    renderTab: PropTypes.func.isRequired,
    onPageChange: PropTypes.func,
  }

  static defaultProps = {
    data: [],
    dev: false,
    lazyrender: false,
    renderAsCarousel: true,
    experimentalMirroring: false,
    fullScreen: true,
    initialPage: {},

    tabContainerPosition: 'top',
    scrollTabsEnabled: false,
    staticTabWidth: VIEWPORT_WIDTH / 2,
    showTabIndicator: true,
    tabIndicatorColor: 'transparent',
    tabIndicatorHeight: 2,

    onPageChange: () => {},
    forceRerenderOnPageChange: false,
  }

  static TABCONTAINER_POSITION = {
    TOP: 'top',
    BOTTOM: 'bottom',
  }

  constructor(props) {
    super(props)

    this.data = this.props.data || []

    this.tabThresholdPages =
      this.props.renderAsCarousel &&
      this.data.length > 1
        ? Math.ceil((VIEWPORT_WIDTH / this.props.staticTabWidth) / 2) + 1
        : 0

    this.contentThresholdPages =
      this.props.renderAsCarousel &&
      this.data.length > 1
        ? 1
        : 0

    this.pageCount = this.props.data.length

    this.summedTabsWidthOverflow = (this.pageCount + this.tabThresholdPages) * this.props.staticTabWidth
      > VIEWPORT_WIDTH
  }

  _getContentProps = () => {
    let contentProps = {}

    Object.keys(this.props).forEach(_key => {

      let isContentProp = true
      switch (_key) {
        case 'data':
        case 'contentContainerStyle':
        case 'renderPage':
        case 'onPageChange':
        case 'onScroll':
          isContentProp = false
      }

      Object.keys(TabbedPager.defaultProps).forEach(_defaultPropKey => {
        if (_key === _defaultPropKey) isContentProp = false
      })

      if (isContentProp) {
        contentProps = Object.assign({}, contentProps, {
          [_key]: this.props[_key],
        })
      }
    })

    return contentProps
  }

  scrollToPage = pageNumber => {
    if (this.contentPager)
      this.contentPager.scrollToPage(pageNumber)
  }

  scrollToIndex = pageIndex => {
    if (this.contentPager)
      this.contentPager.scrollToIndex(pageIndex - this.tabThresholdPages + this.contentThresholdPages)
  }

  _onPageChange = pageNumber => {
    this.props.onPageChange(pageNumber)
    if (this.props.forceRerenderOnPageChange === true)
      this.forceUpdate()
  }

  _onScroll = dx => {
    if (this.tabbar && this.summedTabsWidthOverflow)
      this.tabbar.scroll(dx)
  }

  _renderTabsContainer = (position) => {
    return position === this.props.tabContainerPosition
      ? (
        <View>
          <ViewPager
            ref={tabbar => {
              this.tabbar = tabbar
            }}
            log={false}
            dev={this.props.dev}
            renderAsCarousel={this.props.renderAsCarousel && this.props.data.length > 1}
            data={this.props.data}
            renderPage={this._renderTab}
            pageWidth={this.props.staticTabWidth}
            pagingEnabled={false}
            onShouldSwitchToPage={this.scrollToPage}
            scrollEnabled={this.props.scrollTabsEnabled}
            {...this._getContentProps()}
            thresholdPages={this.tabThresholdPages}
            experimentalMirroring={false}
          />
          {this.props.showTabIndicator && (
            <View
              style={[
                styles.tabIndicator,
                {
                  width: this.props.staticTabWidth,
                  height: this.props.tabIndicatorHeight,
                  backgroundColor: this.props.tabIndicatorColor,
                },
              ]}
            />
          )}
        </View>
      )
      : null
  }

  _renderDividerComponent = (position) => {
    return position === this.props.tabContainerPosition
      ? this.props.DividerComponent
      : null
  }

  _renderTab = ({data, _pageIndex}) => {
    return this.props.renderTab({data, _pageIndex})
  }

  _renderPage = (item) => {
    return this.props.renderPage(item)
  }

  render() {
    return (
      <View style={this.props.fullScreen ? styles.fullScreen : null}>
        {this._renderTabsContainer(TabbedPager.TABCONTAINER_POSITION.TOP)}
        {this._renderDividerComponent(TabbedPager.TABCONTAINER_POSITION.TOP)}
        <ViewPager
          ref={contentPager => {
            this.contentPager = contentPager
          }}
          log={true}
          dev={this.props.dev}
          renderAsCarousel={this.props.renderAsCarousel && this.props.data.length > 1}
          lazyrender={this.props.lazyrender}
          data={this.props.data}
          containerStyle={this.props.fullScreen ? styles.fullScreen : null}
          renderPage={this._renderPage}
          initialPage={this.props.initialPage}
          onPageChange={this._onPageChange}
          onScroll={this._onScroll}
          {...this._getContentProps()}
          thresholdPages={this.contentThresholdPages}
          experimentalMirroring={this.props.experimentalMirroring}
        />
        {this._renderDividerComponent(TabbedPager.TABCONTAINER_POSITION.BOTTOM)}
        {this._renderTabsContainer(TabbedPager.TABCONTAINER_POSITION.BOTTOM)}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  fullScreen: {
    flex: 1,
  },
  tabIndicator: {
    alignSelf: 'center',
  },
})

export default TabbedPager<commit_msg>Change ScrollEnable postion so scrollTabsEnabled works now correktly<commit_after>import React, { PureComponent } from 'react'
import {
  StyleSheet,
  Dimensions,
  View,
} from 'react-native'
import PropTypes from 'prop-types'

import ViewPager from './ViewPager'

const VIEWPORT_WIDTH = Dimensions.get('window').width

class TabbedPager extends PureComponent {

  static propTypes = {
    data: PropTypes.arrayOf(
      PropTypes.object
    ),
    dev: PropTypes.bool,
    lazyrender: PropTypes.bool,
    renderAsCarousel: PropTypes.bool,
    experimentalMirroring: PropTypes.bool,
    fullScreen: PropTypes.bool,
    forceRerenderOnPageChange: PropTypes.bool,
    initialPage: PropTypes.object,

    tabContainerPosition: PropTypes.string,
    scrollTabsEnabled: PropTypes.bool,
    staticTabWidth: PropTypes.number,
    showTabIndicator: PropTypes.bool,
    tabIndicatorColor: PropTypes.string,
    tabIndicatorHeight: PropTypes.number,

    DividerComponent: PropTypes.any,

    renderPage: PropTypes.func.isRequired,
    renderTab: PropTypes.func.isRequired,
    onPageChange: PropTypes.func,
  }

  static defaultProps = {
    data: [],
    dev: false,
    lazyrender: false,
    renderAsCarousel: true,
    experimentalMirroring: false,
    fullScreen: true,
    initialPage: {},

    tabContainerPosition: 'top',
    scrollTabsEnabled: false,
    staticTabWidth: VIEWPORT_WIDTH / 2,
    showTabIndicator: true,
    tabIndicatorColor: 'transparent',
    tabIndicatorHeight: 2,

    onPageChange: () => {},
    forceRerenderOnPageChange: false,
  }

  static TABCONTAINER_POSITION = {
    TOP: 'top',
    BOTTOM: 'bottom',
  }

  constructor(props) {
    super(props)

    this.data = this.props.data || []

    this.tabThresholdPages =
      this.props.renderAsCarousel &&
      this.data.length > 1
        ? Math.ceil((VIEWPORT_WIDTH / this.props.staticTabWidth) / 2) + 1
        : 0

    this.contentThresholdPages =
      this.props.renderAsCarousel &&
      this.data.length > 1
        ? 1
        : 0

    this.pageCount = this.props.data.length

    this.summedTabsWidthOverflow = (this.pageCount + this.tabThresholdPages) * this.props.staticTabWidth
      > VIEWPORT_WIDTH
  }

  _getContentProps = () => {
    let contentProps = {}

    Object.keys(this.props).forEach(_key => {

      let isContentProp = true
      switch (_key) {
        case 'data':
        case 'contentContainerStyle':
        case 'renderPage':
        case 'onPageChange':
        case 'onScroll':
          isContentProp = false
      }

      Object.keys(TabbedPager.defaultProps).forEach(_defaultPropKey => {
        if (_key === _defaultPropKey) isContentProp = false
      })

      if (isContentProp) {
        contentProps = Object.assign({}, contentProps, {
          [_key]: this.props[_key],
        })
      }
    })

    return contentProps
  }

  scrollToPage = pageNumber => {
    if (this.contentPager)
      this.contentPager.scrollToPage(pageNumber)
  }

  scrollToIndex = pageIndex => {
    if (this.contentPager)
      this.contentPager.scrollToIndex(pageIndex - this.tabThresholdPages + this.contentThresholdPages)
  }

  _onPageChange = pageNumber => {
    this.props.onPageChange(pageNumber)
    if (this.props.forceRerenderOnPageChange === true)
      this.forceUpdate()
  }

  _onScroll = dx => {
    if (this.tabbar && this.summedTabsWidthOverflow)
      this.tabbar.scroll(dx)
  }

  _renderTabsContainer = (position) => {
    return position === this.props.tabContainerPosition
      ? (
        <View>
          <ViewPager
            {...this._getContentProps()}
            ref={tabbar => {
              this.tabbar = tabbar
            }}
            log={false}
            dev={this.props.dev}
            renderAsCarousel={this.props.renderAsCarousel && this.props.data.length > 1}
            data={this.props.data}
            renderPage={this._renderTab}
            pageWidth={this.props.staticTabWidth}
            pagingEnabled={false}
            onShouldSwitchToPage={this.scrollToPage}
            scrollEnabled={this.props.scrollTabsEnabled}
            thresholdPages={this.tabThresholdPages}
            experimentalMirroring={false}
          />
          {this.props.showTabIndicator && (
            <View
              style={[
                styles.tabIndicator,
                {
                  width: this.props.staticTabWidth,
                  height: this.props.tabIndicatorHeight,
                  backgroundColor: this.props.tabIndicatorColor,
                },
              ]}
            />
          )}
        </View>
      )
      : null
  }

  _renderDividerComponent = (position) => {
    return position === this.props.tabContainerPosition
      ? this.props.DividerComponent
      : null
  }

  _renderTab = ({data, _pageIndex}) => {
    return this.props.renderTab({data, _pageIndex})
  }

  _renderPage = (item) => {
    return this.props.renderPage(item)
  }

  render() {
    return (
      <View style={this.props.fullScreen ? styles.fullScreen : null}>
        {this._renderTabsContainer(TabbedPager.TABCONTAINER_POSITION.TOP)}
        {this._renderDividerComponent(TabbedPager.TABCONTAINER_POSITION.TOP)}
        <ViewPager
          ref={contentPager => {
            this.contentPager = contentPager
          }}
          log={true}
          dev={this.props.dev}
          renderAsCarousel={this.props.renderAsCarousel && this.props.data.length > 1}
          lazyrender={this.props.lazyrender}
          data={this.props.data}
          containerStyle={this.props.fullScreen ? styles.fullScreen : null}
          renderPage={this._renderPage}
          initialPage={this.props.initialPage}
          onPageChange={this._onPageChange}
          onScroll={this._onScroll}
          {...this._getContentProps()}
          thresholdPages={this.contentThresholdPages}
          experimentalMirroring={this.props.experimentalMirroring}
        />
        {this._renderDividerComponent(TabbedPager.TABCONTAINER_POSITION.BOTTOM)}
        {this._renderTabsContainer(TabbedPager.TABCONTAINER_POSITION.BOTTOM)}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  fullScreen: {
    flex: 1,
  },
  tabIndicator: {
    alignSelf: 'center',
  },
})

export default TabbedPager<|endoftext|>


<commit_before>// Copyright 2002-2014, University of Colorado Boulder

/**
 * Main entry point for the 'Graphing Quadratics' sim.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var DecimalsScreen = require( 'GRAPHING_QUADRATICS/decimals/DecimalsScreen' );
  var IntegersScreen = require( 'GRAPHING_QUADRATICS/integers/IntegersScreen' );
  var Sim = require( 'JOIST/Sim' );
  var SimLauncher = require( 'JOIST/SimLauncher' );
  var VertexFormScreen = require( 'GRAPHING_QUADRATICS/vertexform/VertexFormScreen' );

  // strings
  var title = require( 'string!GRAPHING_QUADRATICS/graphing-quadratics.name' );

  var screens = [ new IntegersScreen(), new DecimalsScreen(), new VertexFormScreen() ];

  var options = {
    credits: {
      leadDesign: 'Karina K. R. Hensberry',
      softwareDevelopment: 'Chris Malley',
      team: 'Mike Dubson, Patricia Loeblein, Ariel Paul, Kathy Perkins'
    }
  };

  SimLauncher.launch( function() {
    var sim = new Sim( title, screens, options );
    sim.start();
  } );
} );<commit_msg>add PixelZoom qualifier to credits<commit_after>// Copyright 2002-2014, University of Colorado Boulder

/**
 * Main entry point for the 'Graphing Quadratics' sim.
 *
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( function( require ) {
  'use strict';

  // modules
  var DecimalsScreen = require( 'GRAPHING_QUADRATICS/decimals/DecimalsScreen' );
  var IntegersScreen = require( 'GRAPHING_QUADRATICS/integers/IntegersScreen' );
  var Sim = require( 'JOIST/Sim' );
  var SimLauncher = require( 'JOIST/SimLauncher' );
  var VertexFormScreen = require( 'GRAPHING_QUADRATICS/vertexform/VertexFormScreen' );

  // strings
  var title = require( 'string!GRAPHING_QUADRATICS/graphing-quadratics.name' );

  var screens = [ new IntegersScreen(), new DecimalsScreen(), new VertexFormScreen() ];

  var options = {
    credits: {
      leadDesign: 'Karina K. R. Hensberry',
      softwareDevelopment: 'Chris Malley (PixelZoom, Inc.)',
      team: 'Mike Dubson, Patricia Loeblein, Ariel Paul, Kathy Perkins'
    }
  };

  SimLauncher.launch( function() {
    var sim = new Sim( title, screens, options );
    sim.start();
  } );
} );<|endoftext|>


<commit_before>/**
 * @file Table component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

// import Header from '../_TableHeader';
import Content from '../_TableContent';
// import Footer from '../_TableFooter';
import Pagination from '../_TablePagination';
import CircularLoading from '../CircularLoading';

import Theme from '../Theme';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';
import ComponentUtil from '../_vendors/ComponentUtil';

class Table extends Component {

    static Theme = Theme;
    static Align = HorizontalAlign;
    static Fixed = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            init: props.hasInitFadeOut,
            sorting: props.sorting,
            page: props.page,
            pageSize: props.pageSize,
            expandRows: props.expandRows,
            value: Calculation.getInitValue(props)
        };

    }

    /**
     * public
     */
    collapseAllRows = () => {
        this.setState({
            expandRows: []
        }, () => {
            const {onExpandChange} = this.props;
            onExpandChange && onExpandChange([]);
        });
    };

    /**
     * keep table loading after do first render
     */
    handleInit = () => {
        this.state.init && this.setState({
            init: false
        });
    };

    /**
     * handle selection change
     */
    handleChange = (value, rowIndex) => {
        this.setState({
            value
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value, rowIndex);
        });
    };

    /**
     * handle sort change
     */
    handleSortChange = sorting => {
        this.setState({
            sorting
        }, () => {
            const {onSortChange} = this.props;
            onSortChange && onSortChange(sorting);
        });
    };

    /**
     * handle pagination change
     */
    handlePaginationChange = pagination => {
        this.setState(pagination, () => {
            const {onPaginationChange} = this.props;
            onPaginationChange && onPaginationChange(pagination);
        });
    };

    /**
     * handle expand change
     */
    handleExpandChange = (expandRows, callback) => {
        this.setState({
            expandRows
        }, () => {
            const {onExpandChange} = this.props;
            onExpandChange && onExpandChange(expandRows);
            callback && callback();
        });
    };

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            sorting: ComponentUtil.getDerivedState(props, state, 'sorting'),
            page: ComponentUtil.getDerivedState(props, state, 'page'),
            pageSize: ComponentUtil.getDerivedState(props, state, 'pageSize'),
            expandRows: ComponentUtil.getDerivedState(props, state, 'expandRows'),
            value: Calculation.getInitValue({
                value: ComponentUtil.getDerivedState(props, state, 'value'),
                selectMode: props.selectMode
            })
        };
    }

    render() {

        const {

                className, style,

                // pagination
                isPaginated, pageSizes, useFullPagination, pageSizeValueField, pageSizeDisplayField,
                paginationSelectionVisible, paginationTotalVisible, paginationPageSizeVisible,
                paginationPageSizesVisible, paginationPageSizeRightIconCls,
                paginationPrevIconCls, paginationNextIconCls, paginationFirstIconCls, paginationLastIconCls,
                paginationTotalRenderer, onPageChange, onPageSizeChange,

                // not passing down these props
                hasInitFadeOut, pageSize: propsPageSize,
                onPaginationChange,

                ...restProps

            } = this.props,
            {init, sorting, page, pageSize, expandRows, value} = this.state;

        return (

                {/* table header, display when select */}
                {/**/}

                {/* table area */}
                <Content {...restProps}
                         sorting={sorting}
                         isPaginated={isPaginated}
                         page={page}
                         pageSize={pageSize}
                         expandRows={expandRows}
                         value={value}
                         onInit={this.handleInit}
                         onChange={this.handleChange}
                         onSortChange={this.handleSortChange}
                         onExpandChange={this.handleExpandChange}/>

                {/* table footer */}
                {/**/}

                {/* table pagination */}
                {
                    isPaginated ?
                        <Pagination {...restProps}
                                    page={page}
                                    pageSize={pageSize}
                                    pageSizes={pageSizes}
                                    value={value}
                                    useFullPagination={useFullPagination}
                                    pageSizeValueField={pageSizeValueField}
                                    pageSizeDisplayField={pageSizeDisplayField}
                                    paginationSelectionVisible={paginationSelectionVisible}
                                    paginationTotalVisible={paginationTotalVisible}
                                    paginationPageSizeVisible={paginationPageSizeVisible}
                                    paginationPageSizesVisible={paginationPageSizesVisible}
                                    paginationPageSizeRightIconCls={paginationPageSizeRightIconCls}
                                    paginationPrevIconCls={paginationPrevIconCls}
                                    paginationNextIconCls={paginationNextIconCls}
                                    paginationFirstIconCls={paginationFirstIconCls}
                                    paginationLastIconCls={paginationLastIconCls}
                                    paginationTotalRenderer={paginationTotalRenderer}
                                    onPageChange={onPageChange}
                                    onPageSizeChange={onPageSizeChange}
                                    onPaginationChange={this.handlePaginationChange}/>
                        :
                        null
                }

                    {
                        init ?
                            <CircularLoading className="table-init-loading"/>
                            :
                            null
                    }

        );

    }
}

Table.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( true / 'left' / 'right' )
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired,

    data: PropTypes.array,
    idProp: PropTypes.string,
    disabled: PropTypes.bool,
    hasInitFadeOut: PropTypes.bool,
    noDataText: PropTypes.string,

    /**
     * expand
     */
    expandRows: PropTypes.array,
    expandIconCls: PropTypes.string,

    /**
     * multi select
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),
    selectColumn: PropTypes.shape({

        /**
         * fixed position of column ( true / 'left' / 'right' )
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))

    }),
    isSelectRecursive: PropTypes.bool,
    selectUncheckedIconCls: PropTypes.string,
    selectCheckedIconCls: PropTypes.string,
    selectIndeterminateIconCls: PropTypes.string,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    autoSorting: PropTypes.bool,
    sortingFunc: PropTypes.func,

    /**
     * pagination
     */
    isPaginated: PropTypes.bool,
    page: PropTypes.number,
    pageSize: PropTypes.number,
    pageSizes: PropTypes.array,
    pageSizeValueField: PropTypes.string,
    pageSizeDisplayField: PropTypes.string,
    useFullPagination: PropTypes.bool,
    paginationSelectionVisible: PropTypes.bool,
    paginationTotalVisible: PropTypes.bool,
    paginationPageSizeVisible: PropTypes.bool,
    paginationPageSizesVisible: PropTypes.bool,
    paginationPageSizeRightIconCls: PropTypes.string,
    paginationPrevIconCls: PropTypes.string,
    paginationNextIconCls: PropTypes.string,
    paginationFirstIconCls: PropTypes.string,
    paginationLastIconCls: PropTypes.string,
    paginationSelectionRenderer: PropTypes.func,
    paginationTotalRenderer: PropTypes.func,

    /**
     * hidden
     */
    isHeadHidden: PropTypes.bool,
    isFootHidden: PropTypes.bool,

    /**
     * fixed
     */
    isHeadFixed: PropTypes.bool,
    isFootFixed: PropTypes.bool,

    /**
     * scroll
     */
    scroll: PropTypes.shape({
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        maxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
    }),

    /**
     * callback
     */
    onChange: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onSelectAll: PropTypes.func,
    onDeselectAll: PropTypes.func,
    onExpand: PropTypes.func,
    onCollapse: PropTypes.func,
    onExpandChange: PropTypes.func,
    onSortChange: PropTypes.func,
    onDataUpdate: PropTypes.func,
    onPaginationChange: PropTypes.func,
    onPageChange: PropTypes.func,
    onPageSizeChange: PropTypes.func

};

Table.defaultProps = {

    disabled: false,
    hasInitFadeOut: true,
    noDataText: 'No Data',

    /**
     * expand
     */
    expandRows: [],
    expandIconCls: 'fas fa-chevron-right',

    /**
     * multi select
     */
    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,
    isSelectRecursive: false,
    selectUncheckedIconCls: 'far fa-square',
    selectCheckedIconCls: 'fas fa-check-square',
    selectIndeterminateIconCls: 'fas fa-minus-square',

    /**
     * sorting
     */
    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',
    autoSorting: true,

    /**
     * pagination
     */
    isPaginated: true,
    page: 0,
    pageSize: 10,
    pageSizes: [5, 10, 15, 20],
    useFullPagination: false,
    pageSizeValueField: 'value',
    pageSizeDisplayField: 'text',
    paginationSelectionVisible: false,
    paginationTotalVisible: true,
    paginationPageSizeVisible: true,
    paginationPageSizesVisible: true,
    paginationPageSizeRightIconCls: 'fas fa-angle-down',
    paginationPrevIconCls: 'fas fa-angle-left',
    paginationNextIconCls: 'fas fa-angle-right',
    paginationFirstIconCls: 'fas fa-angle-double-left',
    paginationLastIconCls: 'fas fa-angle-double-right',

    /**
     * hidden
     */
    isHeadHidden: false,
    isFootHidden: false,

    /**
     * fixed
     */
    isHeadFixed: false,
    isFootFixed: false

};

export default Table;
<commit_msg>update Table<commit_after>/**
 * @file Table component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

// import Header from '../_TableHeader';
import Content from '../_TableContent';
// import Footer from '../_TableFooter';
import Pagination from '../_TablePagination';
import CircularLoading from '../CircularLoading';

import Theme from '../Theme';
import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';
import ComponentUtil from '../_vendors/ComponentUtil';

class Table extends Component {

    static Theme = Theme;
    static Align = HorizontalAlign;
    static Fixed = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            init: props.hasInitFadeOut,
            sorting: props.sorting,
            page: props.page,
            pageSize: props.pageSize,
            expandRows: props.expandRows,
            value: Calculation.getInitValue(props)
        };

    }

    /**
     * public
     */
    collapseAllRows = () => {
        this.setState({
            expandRows: []
        }, () => {
            const {onExpandChange} = this.props;
            onExpandChange && onExpandChange([]);
        });
    };

    /**
     * keep table loading after do first render
     */
    handleInit = () => {
        this.state.init && this.setState({
            init: false
        });
    };

    /**
     * handle selection change
     */
    handleChange = (value, rowIndex) => {
        this.setState({
            value
        }, () => {
            const {onChange} = this.props;
            onChange && onChange(value, rowIndex);
        });
    };

    /**
     * handle sort change
     */
    handleSortChange = sorting => {
        this.setState({
            sorting
        }, () => {
            const {onSortChange} = this.props;
            onSortChange && onSortChange(sorting);
        });
    };

    /**
     * handle pagination change
     */
    handlePaginationChange = pagination => {
        this.setState(pagination, () => {
            const {onPaginationChange} = this.props;
            onPaginationChange && onPaginationChange(pagination);
        });
    };

    /**
     * handle expand change
     */
    handleExpandChange = (expandRows, callback) => {
        this.setState({
            expandRows
        }, () => {
            const {onExpandChange} = this.props;
            onExpandChange && onExpandChange(expandRows);
            callback && callback();
        });
    };

    static getDerivedStateFromProps(props, state) {
        return {
            prevProps: props,
            sorting: ComponentUtil.getDerivedState(props, state, 'sorting'),
            page: ComponentUtil.getDerivedState(props, state, 'page'),
            pageSize: ComponentUtil.getDerivedState(props, state, 'pageSize'),
            expandRows: ComponentUtil.getDerivedState(props, state, 'expandRows'),
            value: Calculation.getInitValue({
                value: ComponentUtil.getDerivedState(props, state, 'value'),
                selectMode: props.selectMode
            })
        };
    }

    render() {

        const {

                className, style,

                // pagination
                isPaginated, pageSizes, useFullPagination, pageSizeValueField, pageSizeDisplayField,
                paginationSelectionVisible, paginationTotalVisible, paginationPageSizeVisible,
                paginationPageSizesVisible, paginationPageSizeRightIconCls,
                paginationPrevIconCls, paginationNextIconCls, paginationFirstIconCls, paginationLastIconCls,
                paginationTotalRenderer, onPageChange, onPageSizeChange,

                // not passing down these props
                hasInitFadeOut, pageSize: propsPageSize,
                onPaginationChange,

                ...restProps

            } = this.props,
            {init, sorting, page, pageSize, expandRows, value} = this.state;

        return (

                {/* table header, display when select */}
                {/**/}

                {/* table area */}
                <Content {...restProps}
                         sorting={sorting}
                         isPaginated={isPaginated}
                         page={page}
                         pageSize={pageSize}
                         expandRows={expandRows}
                         value={value}
                         onInit={this.handleInit}
                         onChange={this.handleChange}
                         onSortChange={this.handleSortChange}
                         onExpandChange={this.handleExpandChange}/>

                {/* table footer */}
                {/**/}

                {/* table pagination */}
                {
                    isPaginated ?
                        <Pagination {...restProps}
                                    page={page}
                                    pageSize={pageSize}
                                    pageSizes={pageSizes}
                                    value={value}
                                    useFullPagination={useFullPagination}
                                    pageSizeValueField={pageSizeValueField}
                                    pageSizeDisplayField={pageSizeDisplayField}
                                    paginationSelectionVisible={paginationSelectionVisible}
                                    paginationTotalVisible={paginationTotalVisible}
                                    paginationPageSizeVisible={paginationPageSizeVisible}
                                    paginationPageSizesVisible={paginationPageSizesVisible}
                                    paginationPageSizeRightIconCls={paginationPageSizeRightIconCls}
                                    paginationPrevIconCls={paginationPrevIconCls}
                                    paginationNextIconCls={paginationNextIconCls}
                                    paginationFirstIconCls={paginationFirstIconCls}
                                    paginationLastIconCls={paginationLastIconCls}
                                    paginationTotalRenderer={paginationTotalRenderer}
                                    onPageChange={onPageChange}
                                    onPageSizeChange={onPageSizeChange}
                                    onPaginationChange={this.handlePaginationChange}/>
                        :
                        null
                }

                    {
                        init ?
                            <CircularLoading className="table-init-loading"/>
                            :
                            null
                    }

        );

    }
}

Table.propTypes = {

    /**
     * The CSS class name of the root element.
     */
    className: PropTypes.string,

    /**
     * Override the styles of the root element.
     */
    style: PropTypes.object,

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( true / 'left' / 'right' ).
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired,

    data: PropTypes.array,
    idProp: PropTypes.string,
    disabled: PropTypes.bool,
    hasInitFadeOut: PropTypes.bool,
    noDataText: PropTypes.string,

    /**
     * expand
     */
    expandRows: PropTypes.array,
    expandIconCls: PropTypes.string,

    /**
     * multi select
     */
    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),
    selectColumn: PropTypes.shape({

        /**
         * fixed position of column ( true / 'left' / 'right' )
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))

    }),
    isSelectRecursive: PropTypes.bool,
    selectUncheckedIconCls: PropTypes.string,
    selectCheckedIconCls: PropTypes.string,
    selectIndeterminateIconCls: PropTypes.string,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),
    defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType)),
    sortingAscIconCls: PropTypes.string,
    sortingDescIconCls: PropTypes.string,
    autoSorting: PropTypes.bool,
    sortingFunc: PropTypes.func,

    /**
     * pagination
     */
    isPaginated: PropTypes.bool,
    page: PropTypes.number,
    pageSize: PropTypes.number,
    pageSizes: PropTypes.array,
    pageSizeValueField: PropTypes.string,
    pageSizeDisplayField: PropTypes.string,
    useFullPagination: PropTypes.bool,
    paginationSelectionVisible: PropTypes.bool,
    paginationTotalVisible: PropTypes.bool,
    paginationPageSizeVisible: PropTypes.bool,
    paginationPageSizesVisible: PropTypes.bool,
    paginationPageSizeRightIconCls: PropTypes.string,
    paginationPrevIconCls: PropTypes.string,
    paginationNextIconCls: PropTypes.string,
    paginationFirstIconCls: PropTypes.string,
    paginationLastIconCls: PropTypes.string,
    paginationSelectionRenderer: PropTypes.func,
    paginationTotalRenderer: PropTypes.func,

    /**
     * hidden
     */
    isHeadHidden: PropTypes.bool,
    isFootHidden: PropTypes.bool,

    /**
     * fixed
     */
    isHeadFixed: PropTypes.bool,
    isFootFixed: PropTypes.bool,

    /**
     * scroll
     */
    scroll: PropTypes.shape({
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        height: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
        maxHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
    }),

    /**
     * callback
     */
    onChange: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onSelectAll: PropTypes.func,
    onDeselectAll: PropTypes.func,
    onExpand: PropTypes.func,
    onCollapse: PropTypes.func,
    onExpandChange: PropTypes.func,
    onSortChange: PropTypes.func,
    onDataUpdate: PropTypes.func,
    onPaginationChange: PropTypes.func,
    onPageChange: PropTypes.func,
    onPageSizeChange: PropTypes.func

};

Table.defaultProps = {

    disabled: false,
    hasInitFadeOut: true,
    noDataText: 'No Data',

    /**
     * expand
     */
    expandRows: [],
    expandIconCls: 'fas fa-chevron-right',

    /**
     * multi select
     */
    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,
    isSelectRecursive: false,
    selectUncheckedIconCls: 'far fa-square',
    selectCheckedIconCls: 'fas fa-check-square',
    selectIndeterminateIconCls: 'fas fa-minus-square',

    /**
     * sorting
     */
    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',
    autoSorting: true,

    /**
     * pagination
     */
    isPaginated: true,
    page: 0,
    pageSize: 10,
    pageSizes: [5, 10, 15, 20],
    useFullPagination: false,
    pageSizeValueField: 'value',
    pageSizeDisplayField: 'text',
    paginationSelectionVisible: false,
    paginationTotalVisible: true,
    paginationPageSizeVisible: true,
    paginationPageSizesVisible: true,
    paginationPageSizeRightIconCls: 'fas fa-angle-down',
    paginationPrevIconCls: 'fas fa-angle-left',
    paginationNextIconCls: 'fas fa-angle-right',
    paginationFirstIconCls: 'fas fa-angle-double-left',
    paginationLastIconCls: 'fas fa-angle-double-right',

    /**
     * hidden
     */
    isHeadHidden: false,
    isFootHidden: false,

    /**
     * fixed
     */
    isHeadFixed: false,
    isFootFixed: false

};

export default Table;
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

lib.rtdep('lib.f', 'lib.Storage');

/**
 * PreferenceManager subclass managing global NaSSH preferences.
 *
 * This is currently just an ordered list of known connection profiles.
 */
hterm.PreferenceManager = function(profileId) {
  lib.PreferenceManager.call(this, hterm.defaultStorage,
                             '/hterm/profiles/' + profileId);
  var defs = hterm.PreferenceManager.defaultPreferences;
  Object.keys(defs).forEach(function(key) {
    this.definePreference(key, defs[key]);
  }.bind(this));
};

hterm.PreferenceManager.defaultPreferences = {
  /**
   * Select an AltGr detection hack^Wheuristic.
   *
   * null: Autodetect based on navigator.language:
   *       'en-us' => 'none', else => 'right-alt'
   * 'none': Disable any AltGr related munging.
   * 'ctrl-alt': Assume Ctrl+Alt means AltGr.
   * 'left-alt': Assume left Alt means AltGr.
   * 'right-alt': Assume right Alt means AltGr.
   */
  'alt-gr-mode': null,

  /**
   * If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that
   * alt-backspace indeed is alt-backspace.
   */
  'alt-backspace-is-meta-backspace': false,

  /**
   * Set whether the alt key acts as a meta key or as a distinct alt key.
   */
  'alt-is-meta': false,

  /**
   * Controls how the alt key is handled.
   *
   *  escape....... Send an ESC prefix.
   *  8-bit........ Add 128 to the unshifted character as in xterm.
   *  browser-key.. Wait for the keypress event and see what the browser says.
   *                (This won't work well on platforms where the browser
   *                 performs a default action for some alt sequences.)
   */
  'alt-sends-what': 'escape',

  /**
   * Terminal bell sound.  Empty string for no audible bell.
   */
  'audible-bell-sound': 'lib-resource:hterm/audio/bell',

  /**
   * If true, terminal bells in the background will create a Web
   * Notification. http://www.w3.org/TR/notifications/
   *
   * Displaying notifications requires permission from the user. When this
   * option is set to true, hterm will attempt to ask the user for permission
   * if necessary. Note browsers may not show this permission request if it
   * did not originate from a user action.
   *
   * Chrome extensions with the "notfications" permission have permission to
   * display notifications.
   */
  'desktop-notification-bell': false,

  /**
   * The background color for text with no other color attributes.
   */
  'background-color': 'rgb(16, 16, 16)',

  /**
   * The background image.
   */
  'background-image': '',

  /**
   * The background image size,
   *
   * Defaults to none.
   */
  'background-size': '',

  /**
   * The background image position,
   *
   * Defaults to none.
   */
  'background-position': '',

  /**
   * If true, the backspace should send BS ('\x08', aka ^H).  Otherwise
   * the backspace key should send '\x7f'.
   */
  'backspace-sends-backspace': false,

  /**
   * Character map overrides.
   *
   * This is specified as an object. It is a sparse array, where each property
   * is the character set code and the value is an object that is a sparse array
   * itself. In that sparse array, each property is the received character and
   * the value is the displayed character.
   *
   * For example:
   *   {"0":{"+":"\u2192",",":"\u2190","-":"\u2191",".":"\u2193","0":"\u2588"}}
   */
  'character-map-overrides': null,

  /**
   * Whether or not to close the window when the command exits.
   */
  'close-on-exit': true,

  /**
   * Whether or not to blink the cursor by default.
   */
  'cursor-blink': false,

  /**
   * The cursor blink rate in milliseconds.
   *
   * A two element array, the first of which is how long the cursor should be
   * on, second is how long it should be off.
   */
  'cursor-blink-cycle': [1000, 500],

  /**
   * The color of the visible cursor.
   */
  'cursor-color': 'rgba(255, 0, 0, 0.5)',

  /**
   * Override colors in the default palette.
   *
   * This can be specified as an array or an object.  If specified as an
   * object it is assumed to be a sparse array, where each property
   * is a numeric index into the color palette.
   *
   * Values can be specified as css almost any css color value.  This
   * includes #RGB, #RRGGBB, rgb(...), rgba(...), and any color names
   * that are also part of the stock X11 rgb.txt file.
   *
   * You can use 'null' to specify that the default value should be not
   * be changed.  This is useful for skipping a small number of indicies
   * when the value is specified as an array.
   */
  'color-palette-overrides': null,

  /**
   * Automatically copy mouse selection to the clipboard.
   */
  'copy-on-select': true,

  /**
   * Whether to use the default window copy behaviour.
   */
  'use-default-window-copy': false,

  /**
   * Whether to clear the selection after copying.
   */
  'clear-selection-after-copy': true,

  /**
   * If true, Ctrl-Plus/Minus/Zero controls zoom.
   * If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_,
   * Ctrl-Plus/Zero do nothing.
   */
  'ctrl-plus-minus-zero-zoom': true,

  /**
   * Ctrl+C copies if true, send ^C to host if false.
   * Ctrl+Shift+C sends ^C to host if true, copies if false.
   */
  'ctrl-c-copy': false,

  /**
   * Ctrl+V pastes if true, send ^V to host if false.
   * Ctrl+Shift+V sends ^V to host if true, pastes if false.
   */
  'ctrl-v-paste': false,

  /**
   * Set whether East Asian Ambiguous characters have two column width.
   */
  'east-asian-ambiguous-as-two-column': false,

  /**
   * True to enable 8-bit control characters, false to ignore them.
   *
   * We'll respect the two-byte versions of these control characters
   * regardless of this setting.
   */
  'enable-8-bit-control': false,

  /**
   * True if we should use bold weight font for text with the bold/bright
   * attribute.  False to use the normal weight font.  Null to autodetect.
   */
  'enable-bold': null,

  /**
   * True if we should use bright colors (8-15 on a 16 color palette)
   * for any text with the bold attribute.  False otherwise.
   */
  'enable-bold-as-bright': true,

  /**
   * Allow the host to write directly to the system clipboard.
   */
  'enable-clipboard-notice': true,

  /**
   * Allow the host to write directly to the system clipboard.
   */
  'enable-clipboard-write': true,

  /**
   * Respect the host's attempt to change the cursor blink status using
   * DEC Private Mode 12.
   */
  'enable-dec12': false,

  /**
   * The default environment variables.
   */
  'environment': {'TERM': 'xterm-256color'},

  /**
   * Default font family for the terminal text.
   */
  'font-family': ('"DejaVu Sans Mono", "Everson Mono", ' +
                  'FreeMono, "Menlo", "Terminal", ' +
                  'monospace'),

  /**
   * The default font size in pixels.
   */
  'font-size': 15,

  /**
   * Anti-aliasing.
   */
  'font-smoothing': 'antialiased',

  /**
   * The foreground color for text with no other color attributes.
   */
  'foreground-color': 'rgb(240, 240, 240)',

  /**
   * If true, home/end will control the terminal scrollbar and shift home/end
   * will send the VT keycodes.  If false then home/end sends VT codes and
   * shift home/end scrolls.
   */
  'home-keys-scroll': false,

  /**
   * Max length of a DCS, OSC, PM, or APS sequence before we give up and
   * ignore the code.
   */
  'max-string-sequence': 100000,

  /**
   * If true, convert media keys to their Fkey equivalent. If false, let
   * Chrome handle the keys.
   */
  'media-keys-are-fkeys': false,

  /**
   * Set whether the meta key sends a leading escape or not.
   */
  'meta-sends-escape': true,

  /**
   * Mouse paste button, or null to autodetect.
   *
   * For autodetect, we'll try to enable middle button paste for non-X11
   * platforms.
   *
   * On X11 we move it to button 3, but that'll probably be a context menu
   * in the future.
   */
  'mouse-paste-button': null,

  /**
   * If true, page up/down will control the terminal scrollbar and shift
   * page up/down will send the VT keycodes.  If false then page up/down
   * sends VT codes and shift page up/down scrolls.
   */
  'page-keys-scroll': false,

  /**
   * Set whether we should pass Alt-1..9 to the browser.
   *
   * This is handy when running hterm in a browser tab, so that you don't lose
   * Chrome's "switch to tab" keyboard accelerators.  When not running in a
   * tab it's better to send these keys to the host so they can be used in
   * vim or emacs.
   *
   * If true, Alt-1..9 will be handled by the browser.  If false, Alt-1..9
   * will be sent to the host.  If null, autodetect based on browser platform
   * and window type.
   */
  'pass-alt-number': null,

  /**
   * Set whether we should pass Ctrl-1..9 to the browser.
   *
   * This is handy when running hterm in a browser tab, so that you don't lose
   * Chrome's "switch to tab" keyboard accelerators.  When not running in a
   * tab it's better to send these keys to the host so they can be used in
   * vim or emacs.
   *
   * If true, Ctrl-1..9 will be handled by the browser.  If false, Ctrl-1..9
   * will be sent to the host.  If null, autodetect based on browser platform
   * and window type.
   */
  'pass-ctrl-number': null,

  /**
   * Set whether we should pass Meta-1..9 to the browser.
   *
   * This is handy when running hterm in a browser tab, so that you don't lose
   * Chrome's "switch to tab" keyboard accelerators.  When not running in a
   * tab it's better to send these keys to the host so they can be used in
   * vim or emacs.
   *
   * If true, Meta-1..9 will be handled by the browser.  If false, Meta-1..9
   * will be sent to the host.  If null, autodetect based on browser platform
   * and window type.
   */
  'pass-meta-number': null,

  /**
   * Set whether meta-V gets passed to host.
   */
  'pass-meta-v': true,

  /**
   * Set the expected encoding for data received from the host.
   *
   * Valid values are 'utf-8' and 'raw'.
   */
  'receive-encoding': 'utf-8',

  /**
   * If true, scroll to the bottom on any keystroke.
   */
  'scroll-on-keystroke': true,

  /**
   * If true, scroll to the bottom on terminal output.
   */
  'scroll-on-output': false,

  /**
   * The vertical scrollbar mode.
   */
  'scrollbar-visible': true,

  /**
   * The multiplier for the pixel delta in mousewheel event caused by the scroll
   * wheel. Alters how fast the page scrolls.
   */
  'scroll-wheel-move-multiplier': 1,

  /**
   * Set the encoding for data sent to host.
   *
   * Valid values are 'utf-8' and 'raw'.
   */
  'send-encoding': 'utf-8',

  /**
   * Shift + Insert pastes if true, sent to host if false.
   */
  'shift-insert-paste': true,

  /**
   * User stylesheet to include in the terminal document.
   */
  'user-css': ''
};

hterm.PreferenceManager.prototype = {
  __proto__: lib.PreferenceManager.prototype
};
<commit_msg>Improve options page<commit_after>// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

'use strict';

lib.rtdep('lib.f', 'lib.Storage');

/**
 * PreferenceManager subclass managing global NaSSH preferences.
 *
 * This is currently just an ordered list of known connection profiles.
 */
hterm.PreferenceManager = function(profileId) {
  lib.PreferenceManager.call(this, hterm.defaultStorage,
                             '/hterm/profiles/' + profileId);
  var defs = hterm.PreferenceManager.defaultPreferences;
  Object.keys(defs).forEach(function(key) {
    this.definePreference(key, defs[key][1]);
  }.bind(this));
};

hterm.PreferenceManager.categories = {};
hterm.PreferenceManager.categories.Keyboard = 'Keyboard';
hterm.PreferenceManager.categories.Appearance = 'Appearance';
hterm.PreferenceManager.categories.CopyPaste = 'CopyPaste';
hterm.PreferenceManager.categories.Sounds = 'Sounds';
hterm.PreferenceManager.categories.Scrolling = 'Scrolling';
hterm.PreferenceManager.categories.Encoding = 'Encoding';
hterm.PreferenceManager.categories.Miscellaneous = 'Miscellaneous';

/**
 * List of categories, ordered by display order (top to bottom)
 */
hterm.PreferenceManager.categoryDefinitions = [
  { id: hterm.PreferenceManager.categories.Appearance,
    text: 'Appearance (fonts, colors, images)'},
  { id: hterm.PreferenceManager.categories.CopyPaste,
    text: 'Copy & Paste'},
  { id: hterm.PreferenceManager.categories.Encoding,
    text: 'Encoding'},
  { id: hterm.PreferenceManager.categories.Keyboard,
    text: 'Keyboard'},
  { id: hterm.PreferenceManager.categories.Scrolling,
    text: 'Scrolling'},
  { id: hterm.PreferenceManager.categories.Sounds,
    text: 'Sounds'},
  { id: hterm.PreferenceManager.categories.Miscellaneous,
    text: 'Misc.'}
];

hterm.PreferenceManager.defaultPreferences = {
  'alt-gr-mode':
  [hterm.PreferenceManager.categories.Keyboard, null,
   [null, 'none', 'ctrl-alt', 'left-alt', 'right-alt'],
   'Select an AltGr detection hack^Wheuristic.\n' +
   '\n' +
   '\'null\': Autodetect based on navigator.language:\n' +
   '      \'en-us\' => \'none\', else => \'right-alt\'\n' +
   '\'none\': Disable any AltGr related munging.\n' +
   '\'ctrl-alt\': Assume Ctrl+Alt means AltGr.\n' +
   '\'left-alt\': Assume left Alt means AltGr.\n' +
   '\'right-alt\': Assume right Alt means AltGr.\n'],

  'alt-backspace-is-meta-backspace':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'If set, undoes the Chrome OS Alt-Backspace->DEL remap, so that ' +
   'alt-backspace indeed is alt-backspace.'],

  'alt-is-meta':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'Set whether the alt key acts as a meta key or as a distinct alt key.'],

  'alt-sends-what':
  [hterm.PreferenceManager.categories.Keyboard, 'escape',
   ['escape', '8-bit', 'browser-key'],
   'Controls how the alt key is handled.\n' +
   '\n' +
   '  escape....... Send an ESC prefix.\n' +
   '  8-bit........ Add 128 to the unshifted character as in xterm.\n' +
   '  browser-key.. Wait for the keypress event and see what the browser \n' +
   '                says.  (This won\'t work well on platforms where the \n' +
   '                browser performs a default action for some alt sequences.)'
  ],

  'audible-bell-sound':
  [hterm.PreferenceManager.categories.Sounds, 'lib-resource:hterm/audio/bell', 'url',
   'URL of the terminal bell sound.  Empty string for no audible bell.'],

  'desktop-notification-bell':
  [hterm.PreferenceManager.categories.Sounds, false, 'bool',
   'If true, terminal bells in the background will create a Web ' +
   'Notification. http://www.w3.org/TR/notifications/\n' +
   '\n'+
   'Displaying notifications requires permission from the user. When this ' +
   'option is set to true, hterm will attempt to ask the user for permission ' +
   'if necessary. Note browsers may not show this permission request if it ' +
   'did not originate from a user action.\n' +
   '\n' +
   'Chrome extensions with the "notifications" permission have permission to ' +
   'display notifications.'],

  'background-color':
  [hterm.PreferenceManager.categories.Appearance, 'rgb(16, 16, 16)', 'color',
   'The background color for text with no other color attributes.'],

  'background-image':
  [hterm.PreferenceManager.categories.Appearance, '', 'string',
   'CSS value of the background image.  Empty string for no image.\n' +
   '\n' +
   'For example:\n' +
   '  url(https://goo.gl/anedTK)\n' +
   '  linear-gradient(top bottom, blue, red)'],

  'background-size':
  [hterm.PreferenceManager.categories.Appearance, '', 'string',
   'CSS value of the background image size.  Defaults to none.'],

  'background-position':
  [hterm.PreferenceManager.categories.Appearance, '', 'string',
   'CSS value of the background image position.\n' +
   '\n' +
   'For example:\n' +
   '  10% 10%\n' +
   '  center'],

  'backspace-sends-backspace':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'If true, the backspace should send BS (\'\\x08\', aka ^H).  Otherwise ' +
   'the backspace key should send \'\\x7f\'.'],

  'character-map-overrides':
  [hterm.PreferenceManager.categories.Keyboard, null, 'value',
    'This is specified as an object. It is a sparse array, where each '  +
    'property is the character set code and the value is an object that is ' +' ' +
    'a sparse array itself. In that sparse array, each property is the ' +
    'received character and the value is the displayed character.\n' +
    '\n' +
    'For example:\n' +
    '  {"0":{"+":"\\u2192",",":"\\u2190","-":"\\u2191",".":"\\u2193", ' +
    '"0":"\\u2588"}}'
  ],

  'close-on-exit':
  [hterm.PreferenceManager.categories.Miscellaneous, true, 'bool',
   'Whether or not to close the window when the command exits.'],

  'cursor-blink':
  [hterm.PreferenceManager.categories.Appearance, false, 'bool',
   'Whether or not to blink the cursor by default.'],

  'cursor-blink-cycle':
  [hterm.PreferenceManager.categories.Appearance, [1000, 500], 'value',
   'The cursor blink rate in milliseconds.\n' +
   '\n' +
   'A two element array, the first of which is how long the cursor should be ' +
   'on, second is how long it should be off.'],

  'cursor-color':
  [hterm.PreferenceManager.categories.Appearance, 'rgba(255, 0, 0, 0.5)', 'color',
   'The color of the visible cursor.'],

  'color-palette-overrides':
  [hterm.PreferenceManager.categories.Appearance, null, 'value',
   'Override colors in the default palette.\n' +
   '\n' +
   'This can be specified as an array or an object.  If specified as an ' +
   'object it is assumed to be a sparse array, where each property ' +
   'is a numeric index into the color palette.\n' +
   '\n' +
   'Values can be specified as almost any css color value.  This ' +
   'includes #RGB, #RRGGBB, rgb(...), rgba(...), and any color names ' +
   'that are also part of the stock X11 rgb.txt file.\n' +
   '\n' +
   'You can use \'null\' to specify that the default value should be not ' +
   'be changed.  This is useful for skipping a small number of indicies ' +
   'when the value is specified as an array.'],

  'copy-on-select':
  [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
   'Automatically copy mouse selection to the clipboard.'],

  'use-default-window-copy':
  [hterm.PreferenceManager.categories.CopyPaste, false, 'bool',
   'Whether to use the default window copy behaviour'],

  'clear-selection-after-copy':
  [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
   'Whether to clear the selection after copying.'],

  'ctrl-plus-minus-zero-zoom':
  [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
   'If true, Ctrl-Plus/Minus/Zero controls zoom.\n' +
   'If false, Ctrl-Shift-Plus/Minus/Zero controls zoom, Ctrl-Minus sends ^_, ' +
   'Ctrl-Plus/Zero do nothing.'],

  'ctrl-c-copy':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'Ctrl+C copies if true, send ^C to host if false.\n' +
   'Ctrl+Shift+C sends ^C to host if true, copies if false.'],

  'ctrl-v-paste':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'Ctrl+V pastes if true, send ^V to host if false.\n' +
   'Ctrl+Shift+V sends ^V to host if true, pastes if false.'],

  'east-asian-ambiguous-as-two-column':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'Set whether East Asian Ambiguous characters have two column width.'],

  'enable-8-bit-control':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'True to enable 8-bit control characters, false to ignore them.\n' +
   '\n' |
   'We\'ll respect the two-byte versions of these control characters ' +
   'regardless of this setting.'],

  'enable-bold':
  [hterm.PreferenceManager.categories.Appearance, null, 'tristate',
   'True if we should use bold weight font for text with the bold/bright ' +
   'attribute.  False to use the normal weight font.  Null to autodetect.'],

  'enable-bold-as-bright':
  [hterm.PreferenceManager.categories.Appearance, true, 'bool',
   'True if we should use bright colors (8-15 on a 16 color palette) ' +
   'for any text with the bold attribute.  False otherwise.'],

  'enable-clipboard-notice':
  [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
   'Show a message in the terminal when the host writes to the clipboard.'],

  'enable-clipboard-write':
  [hterm.PreferenceManager.categories.CopyPaste, true, 'bool',
   'Allow the host to write directly to the system clipboard.'],

  'enable-dec12':
  [hterm.PreferenceManager.categories.Miscellaneous, false, 'bool',
   'Respect the host\'s attempt to change the cursor blink status using ' +
   'DEC Private Mode 12.'],

  'environment':
  [hterm.PreferenceManager.categories.Miscellaneous, {'TERM': 'xterm-256color'}, 'value',
   'The default environment variables, as an object.'],

  'font-family':
  [hterm.PreferenceManager.categories.Appearance,
   '"DejaVu Sans Mono", "Everson Mono", FreeMono, "Menlo", "Terminal", ' +
   'monospace', 'string',
   'Default font family for the terminal text.'],

  'font-size':
  [hterm.PreferenceManager.categories.Appearance, 15, 'int',
   'The default font size in pixels.'],

  'font-smoothing':
  [hterm.PreferenceManager.categories.Appearance, 'antialiased', 'string',
   'CSS font-smoothing property.'],

  'foreground-color':
  [hterm.PreferenceManager.categories.Appearance, 'rgb(240, 240, 240)', 'color',
   'The foreground color for text with no other color attributes.'],

  'home-keys-scroll':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'If true, home/end will control the terminal scrollbar and shift home/end ' +
   'will send the VT keycodes.  If false then home/end sends VT codes and ' +
   'shift home/end scrolls.'],

  'max-string-sequence':
  [hterm.PreferenceManager.categories.Encoding, 100000, 'int',
   'Max length of a DCS, OSC, PM, or APS sequence before we give up and ' +
   'ignore the code.'],

  'media-keys-are-fkeys':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'If true, convert media keys to their Fkey equivalent. If false, let ' +
   'the browser handle the keys.'],

  'meta-sends-escape':
  [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
   'Set whether the meta key sends a leading escape or not.'],

  'mouse-paste-button':
  [hterm.PreferenceManager.categories.CopyPaste, null, [null, 0, 1, 2, 3, 4, 5, 6],
   'Mouse paste button, or null to autodetect.\n' +
   '\n' +
   'For autodetect, we\'ll try to enable middle button paste for non-X11 ' +
   'platforms.  On X11 we move it to button 3.'],

  'page-keys-scroll':
  [hterm.PreferenceManager.categories.Keyboard, false, 'bool',
   'If true, page up/down will control the terminal scrollbar and shift ' +
   'page up/down will send the VT keycodes.  If false then page up/down ' +
   'sends VT codes and shift page up/down scrolls.'],

  'pass-alt-number':
  [hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
   'Set whether we should pass Alt-1..9 to the browser.\n' +
   '\n' +
   'This is handy when running hterm in a browser tab, so that you don\'t ' +
   'lose Chrome\'s "switch to tab" keyboard accelerators.  When not running ' +
   'in a tab it\'s better to send these keys to the host so they can be ' +
   'used in vim or emacs.\n' +
   '\n' +
   'If true, Alt-1..9 will be handled by the browser.  If false, Alt-1..9 ' +
   'will be sent to the host.  If null, autodetect based on browser platform ' +
   'and window type.'],

  'pass-ctrl-number':
  [hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
   'Set whether we should pass Ctrl-1..9 to the browser.\n' +
   '\n' +
   'This is handy when running hterm in a browser tab, so that you don\'t ' +
   'lose Chrome\'s "switch to tab" keyboard accelerators.  When not running ' +
   'in a tab it\'s better to send these keys to the host so they can be ' +
   'used in vim or emacs.\n' +
   '\n' +
   'If true, Ctrl-1..9 will be handled by the browser.  If false, Ctrl-1..9 ' +
   'will be sent to the host.  If null, autodetect based on browser platform ' +
   'and window type.'],

   'pass-meta-number':
  [hterm.PreferenceManager.categories.Keyboard, null, 'tristate',
   'Set whether we should pass Meta-1..9 to the browser.\n' +
   '\n' +
   'This is handy when running hterm in a browser tab, so that you don\'t ' +
   'lose Chrome\'s "switch to tab" keyboard accelerators.  When not running ' +
   'in a tab it\'s better to send these keys to the host so they can be ' +
   'used in vim or emacs.\n' +
   '\n' +
   'If true, Meta-1..9 will be handled by the browser.  If false, Meta-1..9 ' +
   'will be sent to the host.  If null, autodetect based on browser platform ' +
   'and window type.'],

  'pass-meta-v':
  [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
   'Set whether meta-V gets passed to host.'],

  'receive-encoding':
  [hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
   'Set the expected encoding for data received from the host.\n' +
   '\n' +
   'Valid values are \'utf-8\' and \'raw\'.'],

  'scroll-on-keystroke':
  [hterm.PreferenceManager.categories.Scrolling, true, 'bool',
   'If true, scroll to the bottom on any keystroke.'],

  'scroll-on-output':
  [hterm.PreferenceManager.categories.Scrolling, false, 'bool',
   'If true, scroll to the bottom on terminal output.'],

  'scrollbar-visible':
  [hterm.PreferenceManager.categories.Scrolling, true, 'bool',
   'The vertical scrollbar mode.'],

  'scroll-wheel-move-multiplier':
  [hterm.PreferenceManager.categories.Scrolling, 1, 'int',
   'The multiplier for the pixel delta in mousewheel event caused by the ' +
   'scroll wheel. Alters how fast the page scrolls.'],

  'send-encoding':
  [hterm.PreferenceManager.categories.Encoding, 'utf-8', ['utf-8', 'raw'],
   'Set the encoding for data sent to host.'],

  'shift-insert-paste':
  [hterm.PreferenceManager.categories.Keyboard, true, 'bool',
   'Shift + Insert pastes if true, sent to host if false.'],

  'user-css':
  [hterm.PreferenceManager.categories.Appearance, '', 'url',
   'URL of user stylesheet to include in the terminal document.'],
};

hterm.PreferenceManager.prototype = {
  __proto__: lib.PreferenceManager.prototype
};
<|endoftext|>