<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)
        };

    }

    /**
     * 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, isPaginated, pageSizes,
                ...restProps
            } = this.props,
            {init, sorting, page, pageSize, expandRows, value} = this.state;

        return (

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

                {/* table area */}
                <Content {...restProps}
                         sorting={sorting}
                         page={page}
                         pageSize={pageSize}
                         expandRows={expandRows}
                         value={value}
                         isPaginated={isPaginated}
                         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}
                                    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.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

        /**
         * 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
         */
        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
         */
        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
         */
        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,
    expandRows: PropTypes.array,
    noDataText: 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.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

        /**
         * 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,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: 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,
    sortingFunc: PropTypes.func,

    /**
     * pagination
     */
    isPaginated: PropTypes.bool,
    page: PropTypes.number,
    pageSize: PropTypes.number,
    pageSizes: PropTypes.array,
    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.number,
        height: PropTypes.number
    }),

    /**
     * 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,
    onPaginationChange: PropTypes.func,
    onPageChange: PropTypes.func,
    onPageSizeChange: PropTypes.func

};

Table.defaultProps = {

    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,

    disabled: false,
    hasInitFadeOut: true,
    expandRows: [],
    isSelectRecursive: false,
    noDataText: 'No Data',

    uncheckedIconCls: 'far fa-square',
    checkedIconCls: 'fas fa-check-square',
    indeterminateIconCls: 'fas fa-minus-square',

    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',

    isPaginated: true,
    page: 0,
    pageSize: 10,
    pageSizes: [5, 10, 15, 20],
    useFullPagination: false,
    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',

    isHeadHidden: false,
    isFootHidden: false,
    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)
        };

    }

    /**
     * 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, isPaginated, pageSizes,
                ...restProps
            } = this.props,
            {init, sorting, page, pageSize, expandRows, value} = this.state;

        return (

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

                {/* table area */}
                <Content {...restProps}
                         sorting={sorting}
                         page={page}
                         pageSize={pageSize}
                         expandRows={expandRows}
                         value={value}
                         isPaginated={isPaginated}
                         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}
                                    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.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

        /**
         * 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
         */
        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
         */
        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
         */
        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,
    expandRows: PropTypes.array,
    noDataText: 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.number,

        /**
         * minimum width of column
         */
        minWidth: PropTypes.number,

        /**
         * 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,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: 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,
    sortingFunc: PropTypes.func,

    /**
     * pagination
     */
    isPaginated: PropTypes.bool,
    page: PropTypes.number,
    pageSize: PropTypes.number,
    pageSizes: PropTypes.array,
    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.number,
        height: PropTypes.number
    }),

    /**
     * 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,
    onPaginationChange: PropTypes.func,
    onPageChange: PropTypes.func,
    onPageSizeChange: PropTypes.func

};

Table.defaultProps = {

    selectMode: SelectMode.SINGLE_SELECT,
    selectAllMode: SelectAllMode.CURRENT_PAGE,

    disabled: false,
    hasInitFadeOut: true,
    expandRows: [],
    isSelectRecursive: false,
    noDataText: 'No Data',

    uncheckedIconCls: 'far fa-square',
    checkedIconCls: 'fas fa-check-square',
    indeterminateIconCls: 'fas fa-minus-square',

    defaultSortingType: SortingType.ASC,
    sortingAscIconCls: 'fas fa-sort-up',
    sortingDescIconCls: 'fas fa-sort-down',

    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',

    isHeadHidden: false,
    isFootHidden: false,
    isHeadFixed: false,
    isFootFixed: false

};

export default Table;
<|endoftext|>


<commit_before>import blobToBuffer from 'blob-to-buffer';
import EventEmitter2 from 'eventemitter2';

let tcpPolyfillOptions = {
  path: '/',
  secure: false,
  wsProtocols: undefined,
  simulatedLatencyMs: undefined,
};

const notImpl = name => () => {
  throw new Error('Not implemented in TcpPolyfill: ' + name);
};

export function configureTcpPolyfill(options) {
  tcpPolyfillOptions.path = options.path;
  tcpPolyfillOptions.secure = options.secure;
  tcpPolyfillOptions.wsProtocols = options.wsProtocols;
  tcpPolyfillOptions.simulatedLatencyMs = options.simulatedLatencyMs;
}

export function Socket(options) {
  if (!(this instanceof Socket)) {
    return new Socket(options);
  }

  const emitter = new EventEmitter2({});
  ['on', 'once', 'removeListener', 'emit', 'addListener', 'removeAllListeners', 'setMaxListeners', 'listeners'].forEach(method => {
    this[method] = emitter[method].bind(emitter);
  });

  let ws = null;

  this.connect = (port, host, connectListener) => {
    this._simulatedLatencyMs = tcpPolyfillOptions.simulatedLatencyMs;
    const protocol = tcpPolyfillOptions.secure ? 'wss' : 'ws';
    const path = tcpPolyfillOptions.path;
    const url = `${protocol}://${host}:${port}${path}`;
    ws = new WebSocket(url, tcpPolyfillOptions.wsProtocols);
    if (connectListener) {
      emitter.on('connect', connectListener);
    }

    ws.onopen = event => {
      emitter.emit('connect');
    };

    ws.onclose = event => {
      emitter.emit('end');
      emitter.emit('close');
    };

    ws.onerror = event => {
      emitter.emit('error', event);
    };

    ws.onmessage = event => {
      const data = event.data;
      if (typeof Blob !== 'undefined' && data instanceof Blob) {
        blobToBuffer(data, (err, buffer) => {
          if (err) {
            throw err;
          }
          emitter.emit('data', buffer);
        });
      } else if (typeof data === 'string' && ws.protocol === 'base64') {
        emitter.emit('data', new Buffer(data, 'base64'));
      } else {
        emitter.emit('data', data);
      }
    };
  };

  this.end = data => {
    if (data !== undefined) {
      this.write(data);
    }
    ws.close();
  };

  this.destroy = () => {
    ws.close();
  };

  this.write = data => {
    // Convert data (string or node.js Buffer) to ArrayBuffer or base64 string
    // for WebSocket
    let outgoingMessage = null;
    if (ws.protocol === 'base64') {
      outgoingMessage = (new Buffer(data)).toString('base64');
    } else {
      const arrayBuffer = new ArrayBuffer(data.length);
      const view = new Uint8Array(arrayBuffer);
      for (let i = 0; i < data.length; ++i) {
        view[i] = data[i];
      }
      outgoingMessage = arrayBuffer;
    }
    const delay = this._simulatedLatencyMs;
    if (typeof delay === 'number' && delay > 0) {
      setTimeout(() => ws.send(outgoingMessage), delay);
    } else {
      ws.send(outgoingMessage);
    }
  };

  this.setNoDelay = noDelay => {};
  this.setKeepAlive = (enable, initialDelay) => {};

  const notImplMethods = ['setEncoding', 'pause', 'resume', 'setTimeout', 'address', 'unref', 'ref'];
  notImplMethods.forEach(name => {
    this[name] = notImpl(name);
  });
}

export function connect(...args) {
  const opts = {};
  if (args[0] && typeof args[0] === 'object') {
    opts.port = args[0].port;
    opts.host = args[0].host;
    opts.connectListener = args[1];
  } else if (Number(args[0]) > 0) {
    opts.port = args[0];
    opts.host = args[1];
    opts.connectListener = args[2];
  } else {
    throw new Error('Unsupported arguments for net.connect');
  }
  const socket = new Socket();
  socket.connect(opts.port, opts.host, opts.connectListener);
  return socket;
}

export const createConnection = connect;

export const createServer = notImpl('createServer');

// This is wrong, but irrelevant for connecting via websocket
export const isIPv4 = input => true;
export const isIPv6 = input => false;
export const isIP = input => isIPv4(input) ? 4 : isIPv6(input) ? 6 : 0;
<commit_msg>patch to handle a problematic RN environment<commit_after>import blobToBuffer from 'blob-to-buffer';
import EventEmitter2 from 'eventemitter2';

let tcpPolyfillOptions = {
  path: '/',
  secure: false,
  wsProtocols: undefined,
  simulatedLatencyMs: undefined,
};

const notImpl = name => () => {
  throw new Error('Not implemented in TcpPolyfill: ' + name);
};

export function configureTcpPolyfill(options) {
  tcpPolyfillOptions.path = options.path;
  tcpPolyfillOptions.secure = options.secure;
  tcpPolyfillOptions.wsProtocols = options.wsProtocols;
  tcpPolyfillOptions.simulatedLatencyMs = options.simulatedLatencyMs;
}

export function Socket(options) {
  if (!(this instanceof Socket)) {
    return new Socket(options);
  }

  const emitter = new EventEmitter2({});
  ['on', 'once', 'removeListener', 'emit', 'addListener', 'removeAllListeners', 'setMaxListeners', 'listeners'].forEach(method => {
    this[method] = emitter[method].bind(emitter);
  });

  let ws = null;

  this.connect = (port, host, connectListener) => {
    this._simulatedLatencyMs = tcpPolyfillOptions.simulatedLatencyMs;
    const protocol = tcpPolyfillOptions.secure ? 'wss' : 'ws';
    const path = tcpPolyfillOptions.path;
    const url = `${protocol}://${host}:${port}${path}`;
    ws = new WebSocket(url, tcpPolyfillOptions.wsProtocols);
    if (connectListener) {
      emitter.on('connect', connectListener);
    }

    ws.onopen = event => {
      emitter.emit('connect');
    };

    ws.onclose = event => {
      emitter.emit('end');
      emitter.emit('close');
    };

    ws.onerror = event => {
      emitter.emit('error', event);
    };

    ws.onmessage = event => {
      const data = event.data;

      // Handle incoming message as base64 if ws.protocol is set to base64
      // or if it's not set at all and we are in a problematic React Native
      // environment per:
      //
      // https://tools.ietf.org/html/rfc6455#section-11.3.4
      // https://tools.ietf.org/html/rfc3864
      //
      // We check if this process is running inside React Native by using navigator.product:
      //
      // https://github.com/facebook/react-native/commit/3c65e62183ce05893be0822da217cb803b121c61

      const base64SetByWsClient = (
        typeof data === 'string' &&
        ws.protocol === 'base64'
      );

      const base64SetByUser = (
        tcpPolyfillOptions.wsProtocols &&
        tcpPolyfillOptions.wsProtocols.constructor === Array &&
        tcpPolyfillOptions.wsProtocols.indexOf('base64') >= 0
      );

      const isRN = (
        typeof navigator !== 'undefined' &&
        navigator.product === 'ReactNative'
      );

      const base64Workaround = (
        isRN &&
        base64SetByUser &&
        !ws.protocol
      );

      const handleBase64 = base64SetByWsClient || base64Workaround;

      if (typeof Blob !== 'undefined' && data instanceof Blob) {
        blobToBuffer(data, (err, buffer) => {
          if (err) {
            throw err;
          }
          emitter.emit('data', buffer);
        });
      } else if (handleBase64) {
        emitter.emit('data', new Buffer(data, 'base64'));
      } else {
        emitter.emit('data', data);
      }
    };
  };

  this.end = data => {
    if (data !== undefined) {
      this.write(data);
    }
    ws.close();
  };

  this.destroy = () => {
    ws.close();
  };

  this.write = data => {
    // Convert data (string or node.js Buffer) to ArrayBuffer or base64 string
    // for WebSocket
    let outgoingMessage = null;
    if (ws.protocol === 'base64') {
      outgoingMessage = (new Buffer(data)).toString('base64');
    } else {
      const arrayBuffer = new ArrayBuffer(data.length);
      const view = new Uint8Array(arrayBuffer);
      for (let i = 0; i < data.length; ++i) {
        view[i] = data[i];
      }
      outgoingMessage = arrayBuffer;
    }
    const delay = this._simulatedLatencyMs;
    if (typeof delay === 'number' && delay > 0) {
      setTimeout(() => ws.send(outgoingMessage), delay);
    } else {
      ws.send(outgoingMessage);
    }
  };

  this.setNoDelay = noDelay => {};
  this.setKeepAlive = (enable, initialDelay) => {};

  const notImplMethods = ['setEncoding', 'pause', 'resume', 'setTimeout', 'address', 'unref', 'ref'];
  notImplMethods.forEach(name => {
    this[name] = notImpl(name);
  });
}

export function connect(...args) {
  const opts = {};
  if (args[0] && typeof args[0] === 'object') {
    opts.port = args[0].port;
    opts.host = args[0].host;
    opts.connectListener = args[1];
  } else if (Number(args[0]) > 0) {
    opts.port = args[0];
    opts.host = args[1];
    opts.connectListener = args[2];
  } else {
    throw new Error('Unsupported arguments for net.connect');
  }
  const socket = new Socket();
  socket.connect(opts.port, opts.host, opts.connectListener);
  return socket;
}

export const createConnection = connect;

export const createServer = notImpl('createServer');

// This is wrong, but irrelevant for connecting via websocket
export const isIPv4 = input => true;
export const isIPv6 = input => false;
export const isIP = input => isIPv4(input) ? 4 : isIPv6(input) ? 6 : 0;
<|endoftext|>


<commit_before>'use strict';

import blobToBuffer from 'blob-to-buffer';
import EventEmitter2 from 'eventemitter2';

let tcpPolyfillOptions = {
  path: '/',
  secure: false,
  wsProtocols: undefined,
};

const notImpl = name => () => {
  throw new Error('Not implemented in TcpPolyfill: ' + name);
};

export function configureTcpPolyfill(options) {
  tcpPolyfillOptions.path = options.path;
  tcpPolyfillOptions.secure = options.secure;
  tcpPolyfillOptions.wsProtocols = options.wsProtocols;
}

export function Socket(options) {
  if (!(this instanceof Socket)) {
    return new Socket(options);
  }

  const emitter = new EventEmitter2({});
  ['on', 'once', 'removeListener', 'emit', 'addListener', 'removeAllListeners', 'setMaxListeners', 'listeners'].forEach(method => {
    this[method] = emitter[method].bind(emitter);
  });

  let ws = null;

  this.connect = (port, host, connectListener) => {
    const protocol = tcpPolyfillOptions.secure ? 'wss' : 'ws';
    const path = tcpPolyfillOptions.path;
    const url = `${protocol}://${host}:${port}${path}`;
    ws = new WebSocket(url, tcpPolyfillOptions.wsProtocols);
    if (connectListener) {
      emitter.on('connect', connectListener);
    }

    ws.onopen = event => {
      emitter.emit('connect');
    };

    ws.onclose = event => {
      emitter.emit('end');
      emitter.emit('close');
    };

    ws.onerror = event => {
      emitter.emit('error', event.message);
    };

    ws.onmessage = event => {
      const data = event.data;
      if (data instanceof Blob) {
        blobToBuffer(data, (err, buffer) => {
          if (err) {
            throw err;
          }
          emitter.emit('data', buffer);
        });
      } else {
        emitter.emit('data', data);
      }
    };
  };

  this.end = data => {
    if (data !== undefined) {
      ws.send(data);
    }
    ws.close();
  };

  this.destroy = () => {
    ws.close();
  };

  this.write = data => {
    ws.send(data);
  };

  this.setNoDelay = noDelay => {};

  const notImplMethods = ['setEncoding', 'pause', 'resume', 'setTimeout', 'setKeepAlive', 'address', 'unref', 'ref'];
  notImplMethods.forEach(name => {
    this[name] = notImpl(name);
  });
}

export function connect(...args) {
  const opts = {};
  if (args[0] && typeof args[0] === 'object') {
    opts.port = args[0].port;
    opts.host = args[0].host;
    opts.connectListener = args[1];
  } else if (Number(args[0]) > 0) {
    opts.port = args[0];
    opts.host = args[1];
    opts.connectListener = args[2];
  } else {
    throw new Error('Unsupported arguments for net.connect');
  }
  const socket = new Socket();
  socket.connect(opts.port, opts.host, opts.connectListener);
  return socket;
}

export const createConnection = connect;

export const createServer = notImpl('createServer');

// This is wrong, but irrelevant for connecting via websocket
export const isIPv4 = input => true;
export const isIPv6 = input => false;
export const isIP = input => isIPv4(input) ? 4 : isIPv6(input) ? 6 : 0;
<commit_msg>Propagate entire error from websocket to socket<commit_after>'use strict';

import blobToBuffer from 'blob-to-buffer';
import EventEmitter2 from 'eventemitter2';

let tcpPolyfillOptions = {
  path: '/',
  secure: false,
  wsProtocols: undefined,
};

const notImpl = name => () => {
  throw new Error('Not implemented in TcpPolyfill: ' + name);
};

export function configureTcpPolyfill(options) {
  tcpPolyfillOptions.path = options.path;
  tcpPolyfillOptions.secure = options.secure;
  tcpPolyfillOptions.wsProtocols = options.wsProtocols;
}

export function Socket(options) {
  if (!(this instanceof Socket)) {
    return new Socket(options);
  }

  const emitter = new EventEmitter2({});
  ['on', 'once', 'removeListener', 'emit', 'addListener', 'removeAllListeners', 'setMaxListeners', 'listeners'].forEach(method => {
    this[method] = emitter[method].bind(emitter);
  });

  let ws = null;

  this.connect = (port, host, connectListener) => {
    const protocol = tcpPolyfillOptions.secure ? 'wss' : 'ws';
    const path = tcpPolyfillOptions.path;
    const url = `${protocol}://${host}:${port}${path}`;
    ws = new WebSocket(url, tcpPolyfillOptions.wsProtocols);
    if (connectListener) {
      emitter.on('connect', connectListener);
    }

    ws.onopen = event => {
      emitter.emit('connect');
    };

    ws.onclose = event => {
      emitter.emit('end');
      emitter.emit('close');
    };

    ws.onerror = event => {
      emitter.emit('error', event);
    };

    ws.onmessage = event => {
      const data = event.data;
      if (data instanceof Blob) {
        blobToBuffer(data, (err, buffer) => {
          if (err) {
            throw err;
          }
          emitter.emit('data', buffer);
        });
      } else {
        emitter.emit('data', data);
      }
    };
  };

  this.end = data => {
    if (data !== undefined) {
      ws.send(data);
    }
    ws.close();
  };

  this.destroy = () => {
    ws.close();
  };

  this.write = data => {
    ws.send(data);
  };

  this.setNoDelay = noDelay => {};

  const notImplMethods = ['setEncoding', 'pause', 'resume', 'setTimeout', 'setKeepAlive', 'address', 'unref', 'ref'];
  notImplMethods.forEach(name => {
    this[name] = notImpl(name);
  });
}

export function connect(...args) {
  const opts = {};
  if (args[0] && typeof args[0] === 'object') {
    opts.port = args[0].port;
    opts.host = args[0].host;
    opts.connectListener = args[1];
  } else if (Number(args[0]) > 0) {
    opts.port = args[0];
    opts.host = args[1];
    opts.connectListener = args[2];
  } else {
    throw new Error('Unsupported arguments for net.connect');
  }
  const socket = new Socket();
  socket.connect(opts.port, opts.host, opts.connectListener);
  return socket;
}

export const createConnection = connect;

export const createServer = notImpl('createServer');

// This is wrong, but irrelevant for connecting via websocket
export const isIPv4 = input => true;
export const isIPv6 = input => false;
export const isIP = input => isIPv4(input) ? 4 : isIPv6(input) ? 6 : 0;
<|endoftext|>


<commit_before>
//Adds new Settings Tab Panel if not created or show settingsTab else.
function showSettingsTabPanel(navBarList, panelContainer){
  var settingsTabId = "Settings";
  var settingsTab = getTabForSelector(settingsTabId);
  if (getTabForSelector(settingsTabId) == null) {
    settingsTab = new SettingsTabPanel(settingsTabId, "TabPanelTemplate", "NavItem_" + tabPanels.length, theService, navBarList, panelContainer);
  } else {
    settingsTab.show();
  }
}

function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, panelContainer) {

  var currentObj = this;
  tabPanels.push(this); // Insert on tabPanels here for preparing access to getTabForSelector from plots

  TabPanel.call(this, id, classSelector, navItemClass, navBarList, panelContainer);
  this.setTitle("Settings");

  this.getPageName = function () {
    return "GeneralSettingsPage";
  }

  this.$container = this.$html.find(".toolPanelContainer");
  this.$container.html('
' +
                          'About DAVE ' +
                        '
' +
                        '
' +
                          '
' +
                            'General Settings:' +
                          '
' +
                          '
' +
                            '
' +
                              'Main settings:' +
                            '
' +
                            '
' +
                            '
' +
                          '
' +
                          '
' +
                            '
' +
                              'Power density spectrum settings:' +
                            '
' +
                            '
' +
                            '
' +
                            '
' +
                              'Advanced settings:' +
                            '
' +
                            '
' +
                            '
' +
                        '
' +
                      '
' +
                      '
Settings changed here only applies to new tabs. You can save the workspace for reusing this settings later, or edit config.js file to update the default settings.
' +
                    '

');

  var $mainSettings = this.$container.find(".mainSettings");
  var $segmSettings = this.$container.find(".segmSettings");
  var $advSettingss = this.$container.find(".advSettings");

  /* Shows the auto BinSize or time filtering choice
    $mainSettings.append(getRadioControl(currentObj.id,
                                    "Auto Filtering",
                                    "autoFilterType",
                                    [
                                      { id:"Time", label:"Time range", value:"Time" },
                                      { id:"BinSize", label:"Bin size", value:"BinSize" }
                                    ],
                                    (CONFIG.AUTO_BINSIZE) ? "BinSize" : "Time",
                                    function(value, id) {
                                      CONFIG.AUTO_BINSIZE = (value == "BinSize");
                                      updateServerConfig();
                                    }));*/

  $mainSettings.append(getInlineRangeBox ("MIN_PLOT_POINTS_" + this.id, "inputMIN_PLOT_POINTS",
                                    "Minimum points to plot", CONFIG.MIN_PLOT_POINTS, 2, CONFIG.MAX_PLOT_POINTS,
                                    function(value, input) { CONFIG.MIN_PLOT_POINTS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("MAX_PLOT_POINTS_" + this.id, "inputMAX_PLOT_POINTS",
                                    "Maximum points to plot", CONFIG.MAX_PLOT_POINTS, CONFIG.MIN_PLOT_POINTS, 9999999,
                                    function(value, input) { CONFIG.MAX_PLOT_POINTS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("MAX_TIME_RESOLUTION_DECIMALS_" + this.id, "inputMAX_TIME_RESOLUTION_DECIMALS",
                                    "Maximum time resolution", CONFIG.MAX_TIME_RESOLUTION_DECIMALS, 1, 9,
                                    function(value, input) { CONFIG.MAX_TIME_RESOLUTION_DECIMALS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("MAX_TIME_RESOLUTION_DECIMALS_" + this.id, "inputMAX_TIME_RESOLUTION_DECIMALS",
                                    "Time decimals", CONFIG.MAX_TIME_RESOLUTION_DECIMALS, 1, 9,
                                    function(value, input) { CONFIG.MAX_TIME_RESOLUTION_DECIMALS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("DEFAULT_NUMBER_DECIMALS_" + this.id, "inputDEFAULT_NUMBER_DECIMALS",
                                    "Default decimals", CONFIG.DEFAULT_NUMBER_DECIMALS, 1, 9,
                                    function(value, input) { CONFIG.DEFAULT_NUMBER_DECIMALS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("SERVER_DATA_PRECISION_" + this.id, "inputSERVER_DATA_PRECISION",
                                    "Decimals of the data given by server", CONFIG.SERVER_DATA_PRECISION, 1, 12,
                                    function(value, input) { CONFIG.SERVER_DATA_PRECISION = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("FRACEXP_LIMIT_" + this.id, "inputFRACEXP_LIMIT float",
                                    "Minimum exposure fraction allowed", CONFIG.FRACEXP_LIMIT, 0.0, 1.0,
                                    function(value, input) { CONFIG.FRACEXP_LIMIT = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("ENERGY_FILTER_STEP_" + this.id, "inputENERGY_FILTER_STEP float",
                                    "Step value for energy filters in keV (default: 5eV)", CONFIG.ENERGY_FILTER_STEP, 0.0001, 0.1,
                                    function(value, input) { CONFIG.ENERGY_FILTER_STEP = value; updateServerConfig(); }));

  $segmSettings.append(getInlineRangeBox ("MIN_SEGMENT_MULTIPLIER_" + this.id, "inputMIN_SEGMENT_MULTIPLIER",
                                    "Minimum segment size: BinSize *", CONFIG.MIN_SEGMENT_MULTIPLIER, 1, 100,
                                    function(value, input) { CONFIG.MIN_SEGMENT_MULTIPLIER = value; updateServerConfig(); }));

  $segmSettings.append(getInlineRangeBox ("DEFAULT_SEGMENT_DIVIDER_" + this.id, "inputDEFAULT_SEGMENT_DIVIDER",
                                    "Default segment size: TotalTime /", CONFIG.DEFAULT_SEGMENT_DIVIDER, 1, 100,
                                    function(value, input) { CONFIG.DEFAULT_SEGMENT_DIVIDER = value; updateServerConfig(); }));

  $advSettingss.append(getTextBox ("TIME_COLUMN_" + this.id, "inputTIME_COLUMN",
                                    "Time column name on HDU", CONFIG.TIME_COLUMN,
                                    function(value, input) { CONFIG.TIME_COLUMN = value; updateServerConfig(); }));

  $advSettingss.append(getTextBox ("EVENTS_STRING_" + this.id, "inputEVENTS_STRING width80",
                                    "HDU names supported as EVENT tables (separated by commas without spaces)", CONFIG.EVENTS_STRING,
                                    function(value, input) { CONFIG.EVENTS_STRING = value; updateServerConfig(); }));

  $advSettingss.append(getTextBox ("GTI_STRING_" + this.id, "inputGTI_STRING width80",
                                    "HDU names supported as GTI tables (separated by commas without spaces)", CONFIG.GTI_STRING,
                                    function(value, input) { CONFIG.GTI_STRING = value; updateServerConfig(); }));

  $advSettingss.append(getBooleanBox ("Avoid set background light curve if it is already subtracted",
                                    "chkDENY_BCK_IF_SUBS", CONFIG.DENY_BCK_IF_SUBS,
                                    function(enabled) { CONFIG.DENY_BCK_IF_SUBS = enabled; updateServerConfig(); }));

  $advSettingss.append(getBooleanBox ("Show server logs on GUI Log tab",
                                    "chkLOG_TO_SERVER_ENABLED", CONFIG.LOG_TO_SERVER_ENABLED,
                                    function(enabled) { CONFIG.LOG_TO_SERVER_ENABLED = enabled; updateServerConfig(); }));

  //Add the server log level radio buttons
  // PYTHON SERVER LOG LEVEL -> ALL = -1, DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3, NONE = 4
  $advSettingss.append(getRadioControl(currentObj.id,
                                    "Server logging level",
                                    "serverLogLevel",
                                    [
                                      { id:"All", label:"All", value:"-1" },
                                      { id:"Debug", label:"Debug", value:"0" },
                                      { id:"Info", label:"Info", value:"1" },
                                      { id:"Warn", label:"Warn", value:"2" },
                                      { id:"Error", label:"Error", value:"3" },
                                      { id:"None", label:"None", value:"4" }
                                    ],
                                    CONFIG.LOG_LEVEL + "",
                                    function(value, id) {
                                      CONFIG.LOG_LEVEL = parseInt(value);
                                      updateServerConfig();
                                    },
                                    "smallTextStyle"));

  var $btnClearCache = $('<button class="btn btn-default btnClearCache" style="padding-right: 10px; padding-left: 10px; margin-top: 14px;" data-toggle="tooltip" title="Clear server cache"> Clear server cache</button>');
  $btnClearCache.click(function(event){
    theService.clear_cache(function (res) {
      logInfo("Server cache clean!");
      currentObj.$container.find(".btnClearCache").html(' Server cache clean!');
      setTimeout(function () {
        currentObj.$container.find(".btnClearCache").html(' Clear server cache');
      }, 2000);
    });
  });
  $advSettingss.append($btnClearCache);

  this.$container.find(".btnAboutDave").click(function () {

    var version = !isNull(BUILD_VERSION) ? BUILD_VERSION : "Unknown";

    showMsg("About DAVE",
            "
DAVE stands for Data Analysis of Variable Events, which is a GUI built on top of the Stingray library. It is intended to be used by astronomers for time-series analysis in general, and analysis of variable sources in particular.
The goal is to enable scientific exploration and flexible analysis flows where users can insert their own algorithms to compare the effects of such changes.
" +
            "
More information about DAVE in:
https://github.com/StingraySoftware/dave
" +
            "
© 2016 Timelab Technologies Ltd.
" +
            "
DAVE Version: " + version + "
");

    gaTracker.sendEvent("GeneralSettings", "btnAboutDave", currentObj.id);
  });

  log("SettingsTabPanel ready! id: " + this.id);
  return this;
}
<commit_msg>DAVE-349: Little text change in general setting<commit_after>
//Adds new Settings Tab Panel if not created or show settingsTab else.
function showSettingsTabPanel(navBarList, panelContainer){
  var settingsTabId = "Settings";
  var settingsTab = getTabForSelector(settingsTabId);
  if (getTabForSelector(settingsTabId) == null) {
    settingsTab = new SettingsTabPanel(settingsTabId, "TabPanelTemplate", "NavItem_" + tabPanels.length, theService, navBarList, panelContainer);
  } else {
    settingsTab.show();
  }
}

function SettingsTabPanel (id, classSelector, navItemClass, service, navBarList, panelContainer) {

  var currentObj = this;
  tabPanels.push(this); // Insert on tabPanels here for preparing access to getTabForSelector from plots

  TabPanel.call(this, id, classSelector, navItemClass, navBarList, panelContainer);
  this.setTitle("Settings");

  this.getPageName = function () {
    return "GeneralSettingsPage";
  }

  this.$container = this.$html.find(".toolPanelContainer");
  this.$container.html('
' +
                          'About DAVE ' +
                        '
' +
                        '
' +
                          '
' +
                            'General Settings:' +
                          '
' +
                          '
' +
                            '
' +
                              'Main settings:' +
                            '
' +
                            '
' +
                            '
' +
                          '
' +
                          '
' +
                            '
' +
                              'Power density spectrum settings:' +
                            '
' +
                            '
' +
                            '
' +
                            '
' +
                              'Advanced settings:' +
                            '
' +
                            '
' +
                            '
' +
                        '
' +
                      '
' +
                      '
Settings changed here only applies to new tabs. You can save the workspace to reuse this settings later, or edit config.js file to update the default settings.
' +
                    '

');

  var $mainSettings = this.$container.find(".mainSettings");
  var $segmSettings = this.$container.find(".segmSettings");
  var $advSettingss = this.$container.find(".advSettings");

  /* Shows the auto BinSize or time filtering choice
    $mainSettings.append(getRadioControl(currentObj.id,
                                    "Auto Filtering",
                                    "autoFilterType",
                                    [
                                      { id:"Time", label:"Time range", value:"Time" },
                                      { id:"BinSize", label:"Bin size", value:"BinSize" }
                                    ],
                                    (CONFIG.AUTO_BINSIZE) ? "BinSize" : "Time",
                                    function(value, id) {
                                      CONFIG.AUTO_BINSIZE = (value == "BinSize");
                                      updateServerConfig();
                                    }));*/

  $mainSettings.append(getInlineRangeBox ("MIN_PLOT_POINTS_" + this.id, "inputMIN_PLOT_POINTS",
                                    "Minimum points to plot", CONFIG.MIN_PLOT_POINTS, 2, CONFIG.MAX_PLOT_POINTS,
                                    function(value, input) { CONFIG.MIN_PLOT_POINTS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("MAX_PLOT_POINTS_" + this.id, "inputMAX_PLOT_POINTS",
                                    "Maximum points to plot", CONFIG.MAX_PLOT_POINTS, CONFIG.MIN_PLOT_POINTS, 9999999,
                                    function(value, input) { CONFIG.MAX_PLOT_POINTS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("MAX_TIME_RESOLUTION_DECIMALS_" + this.id, "inputMAX_TIME_RESOLUTION_DECIMALS",
                                    "Maximum time resolution", CONFIG.MAX_TIME_RESOLUTION_DECIMALS, 1, 9,
                                    function(value, input) { CONFIG.MAX_TIME_RESOLUTION_DECIMALS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("MAX_TIME_RESOLUTION_DECIMALS_" + this.id, "inputMAX_TIME_RESOLUTION_DECIMALS",
                                    "Time decimals", CONFIG.MAX_TIME_RESOLUTION_DECIMALS, 1, 9,
                                    function(value, input) { CONFIG.MAX_TIME_RESOLUTION_DECIMALS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("DEFAULT_NUMBER_DECIMALS_" + this.id, "inputDEFAULT_NUMBER_DECIMALS",
                                    "Default decimals", CONFIG.DEFAULT_NUMBER_DECIMALS, 1, 9,
                                    function(value, input) { CONFIG.DEFAULT_NUMBER_DECIMALS = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("SERVER_DATA_PRECISION_" + this.id, "inputSERVER_DATA_PRECISION",
                                    "Decimals of the data given by server", CONFIG.SERVER_DATA_PRECISION, 1, 12,
                                    function(value, input) { CONFIG.SERVER_DATA_PRECISION = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("FRACEXP_LIMIT_" + this.id, "inputFRACEXP_LIMIT float",
                                    "Minimum exposure fraction allowed", CONFIG.FRACEXP_LIMIT, 0.0, 1.0,
                                    function(value, input) { CONFIG.FRACEXP_LIMIT = value; updateServerConfig(); }));

  $mainSettings.append(getInlineRangeBox ("ENERGY_FILTER_STEP_" + this.id, "inputENERGY_FILTER_STEP float",
                                    "Step value for energy filters in keV (default: 5eV)", CONFIG.ENERGY_FILTER_STEP, 0.0001, 0.1,
                                    function(value, input) { CONFIG.ENERGY_FILTER_STEP = value; updateServerConfig(); }));

  $segmSettings.append(getInlineRangeBox ("MIN_SEGMENT_MULTIPLIER_" + this.id, "inputMIN_SEGMENT_MULTIPLIER",
                                    "Minimum segment size: BinSize *", CONFIG.MIN_SEGMENT_MULTIPLIER, 1, 100,
                                    function(value, input) { CONFIG.MIN_SEGMENT_MULTIPLIER = value; updateServerConfig(); }));

  $segmSettings.append(getInlineRangeBox ("DEFAULT_SEGMENT_DIVIDER_" + this.id, "inputDEFAULT_SEGMENT_DIVIDER",
                                    "Default segment size: TotalTime /", CONFIG.DEFAULT_SEGMENT_DIVIDER, 1, 100,
                                    function(value, input) { CONFIG.DEFAULT_SEGMENT_DIVIDER = value; updateServerConfig(); }));

  $advSettingss.append(getTextBox ("TIME_COLUMN_" + this.id, "inputTIME_COLUMN",
                                    "Time column name on HDU", CONFIG.TIME_COLUMN,
                                    function(value, input) { CONFIG.TIME_COLUMN = value; updateServerConfig(); }));

  $advSettingss.append(getTextBox ("EVENTS_STRING_" + this.id, "inputEVENTS_STRING width80",
                                    "HDU names supported as EVENT tables (separated by commas without spaces)", CONFIG.EVENTS_STRING,
                                    function(value, input) { CONFIG.EVENTS_STRING = value; updateServerConfig(); }));

  $advSettingss.append(getTextBox ("GTI_STRING_" + this.id, "inputGTI_STRING width80",
                                    "HDU names supported as GTI tables (separated by commas without spaces)", CONFIG.GTI_STRING,
                                    function(value, input) { CONFIG.GTI_STRING = value; updateServerConfig(); }));

  $advSettingss.append(getBooleanBox ("Avoid set background light curve if it is already subtracted",
                                    "chkDENY_BCK_IF_SUBS", CONFIG.DENY_BCK_IF_SUBS,
                                    function(enabled) { CONFIG.DENY_BCK_IF_SUBS = enabled; updateServerConfig(); }));

  $advSettingss.append(getBooleanBox ("Show server logs on GUI Log tab",
                                    "chkLOG_TO_SERVER_ENABLED", CONFIG.LOG_TO_SERVER_ENABLED,
                                    function(enabled) { CONFIG.LOG_TO_SERVER_ENABLED = enabled; updateServerConfig(); }));

  //Add the server log level radio buttons
  // PYTHON SERVER LOG LEVEL -> ALL = -1, DEBUG = 0, INFO = 1, WARN = 2, ERROR = 3, NONE = 4
  $advSettingss.append(getRadioControl(currentObj.id,
                                    "Server logging level",
                                    "serverLogLevel",
                                    [
                                      { id:"All", label:"All", value:"-1" },
                                      { id:"Debug", label:"Debug", value:"0" },
                                      { id:"Info", label:"Info", value:"1" },
                                      { id:"Warn", label:"Warn", value:"2" },
                                      { id:"Error", label:"Error", value:"3" },
                                      { id:"None", label:"None", value:"4" }
                                    ],
                                    CONFIG.LOG_LEVEL + "",
                                    function(value, id) {
                                      CONFIG.LOG_LEVEL = parseInt(value);
                                      updateServerConfig();
                                    },
                                    "smallTextStyle"));

  var $btnClearCache = $('<button class="btn btn-default btnClearCache" style="padding-right: 10px; padding-left: 10px; margin-top: 14px;" data-toggle="tooltip" title="Clear server cache"> Clear server cache</button>');
  $btnClearCache.click(function(event){
    theService.clear_cache(function (res) {
      logInfo("Server cache clean!");
      currentObj.$container.find(".btnClearCache").html(' Server cache clean!');
      setTimeout(function () {
        currentObj.$container.find(".btnClearCache").html(' Clear server cache');
      }, 2000);
    });
  });
  $advSettingss.append($btnClearCache);

  this.$container.find(".btnAboutDave").click(function () {

    var version = !isNull(BUILD_VERSION) ? BUILD_VERSION : "Unknown";

    showMsg("About DAVE",
            "
DAVE stands for Data Analysis of Variable Events, which is a GUI built on top of the Stingray library. It is intended to be used by astronomers for time-series analysis in general, and analysis of variable sources in particular.
The goal is to enable scientific exploration and flexible analysis flows where users can insert their own algorithms to compare the effects of such changes.
" +
            "
More information about DAVE in:
https://github.com/StingraySoftware/dave
" +
            "
© 2016 Timelab Technologies Ltd.
" +
            "
DAVE Version: " + version + "
");

    gaTracker.sendEvent("GeneralSettings", "btnAboutDave", currentObj.id);
  });

  log("SettingsTabPanel ready! id: " + this.id);
  return this;
}
<|endoftext|>


<commit_before>app.controller('mainCtrl', function($scope, $rootScope, $http, $location, Config){
	// Inicializar variables utilizadas en todo el codigo y que provienen de la sesion del usuario
	$scope.user = function(user) {
		$rootScope.user = JSON.parse(user);
		console.log(user);
		Config.insigniasPorSeccion($rootScope.user.seccion).then(function(data){
			console.log(data);
			$rootScope.area1 = data.area1;
			$rootScope.area2 = data.area2;
			$rootScope.area3 = data.area3;
			$rootScope.area4 = data.area4;
			$rootScope.area5 = data.area5;
			$rootScope.area6 = data.area6;
			$rootScope.objetivo = data.objetivo;
			$rootScope.totalseccion = data.totalseccion;
			$rootScope.user.clan = data.user.clan;
			$rootScope.user.pequenogrupo = data.user.pequenogrupo;
			$rootScope.insignias = Object.values(data.insignias);
		});
		Config.radiosFichaMedica().then(function(data){
			$rootScope.radios = data;
		});

	}

	// Manejar el menu responsivo para tamaño movil
	$scope.windowWidth= window.innerWidth;
	$(window).resize(function(){
		$scope.$apply(function(){
			console.log($rootScope.user);
		   $scope.windowWidth= window.innerWidth;
		   if ($scope.windowWidth < 768) {
				   $scope.toggle = false;
		   }
		});
	});

	$scope.isActive = function(route) {
		return route === $location.path();
	}

	$rootScope.parseArea = function(seccion){
		Config.areaYObjetivoPorSeccion(seccion, "").then(function(data){
			return data.area;
		});
	};
	$rootScope.parseObjetivo= function(seccion, area){
		Config.areaYObjetivoPorSeccion(seccion, area).then(function(data){
			return data.objetivo;
		});
	};

});
<commit_msg>Update mainCtrl.js<commit_after>app.controller('mainCtrl', function($scope, $rootScope, $http, $location, Config){
	// Inicializar variables utilizadas en todo el codigo y que provienen de la sesion del usuario
	$scope.user = function(user) {
		$rootScope.user = JSON.parse(user);
		console.log(user);
		Config.insigniasPorSeccion($rootScope.user.seccion).then(function(data){
			console.log(data);
			$rootScope.area1 = data.area1;
			$rootScope.area2 = data.area2;
			$rootScope.area3 = data.area3;
			$rootScope.area4 = data.area4;
			$rootScope.area5 = data.area5;
			$rootScope.area6 = data.area6;
			$rootScope.objetivo = data.objetivo;
			$rootScope.totalseccion = data.totalseccion;
			$rootScope.user.clan = data.user.clan;
			$rootScope.user.pequenogrupo = data.user.pequenogrupo;
			$rootScope.insignias = Object.values(data.insignias);
		});
		Config.radiosFichaMedica().then(function(data){
			$rootScope.radios = data;
		});

	}

	// Manejar el menu responsivo para tamaño movil
	$scope.windowWidth= window.innerWidth;
	$(window).resize(function(){
		$scope.$apply(function(){
			console.log($rootScope.user);
		   $scope.windowWidth= window.innerWidth;
		   if ($scope.windowWidth < 768) {
				   $scope.toggle = false;
		   }
		});
	});

	$scope.isActive = function(route) {
		return route === $location.path();
	}

});
<|endoftext|>


<commit_before>(function(){
	'use strict';

	angular
		.module('responsiveGrid')
		.controller('HomeController', HomeController);

	HomeController.$inject = ['$scope', '$log', '$location', 'DataService'];

	function HomeController($scope, $log, $location, DataService) {
		/*jshint validthis: true*/
		var vm = this;
		vm.layoutType = 'grid';
		vm.page = {
			header: "The Grid",
			description: "A digital frontier. I tried to imagine what custom responsive grids looked like in the CSS engine. Were they lanyards in a swimming pool, white-picket fences, or something else entirely?",
			credit: "Content was sourced from TheGuardian.com."
		}; //vm.page{}

		vm.tiles = DataService.data;
		vm.linkToSite = linkToSite;

		//Functions
		function linkToSite(link) {
			console.log(link); //REMOVE THIS WHEN DONE TESTING
			$location.url(link);
		}

	} //HomeController()

}()); //IIFE<commit_msg>Removed Deprecated Function<commit_after>(function(){
	'use strict';

	angular
		.module('responsiveGrid')
		.controller('HomeController', HomeController);

	HomeController.$inject = ['$scope', '$log', '$location', 'DataService'];

	function HomeController($scope, $log, $location, DataService) {
		/*jshint validthis: true*/
		var vm = this;
		vm.layoutType = 'grid';
		vm.page = {
			header: "The Grid",
			description: "A digital frontier. I tried to imagine what custom responsive grids looked like in the CSS engine. Were they lanyards in a swimming pool, white-picket fences, or something else entirely?",
			credit: "Content was sourced from TheGuardian.com."
		}; //vm.page{}

		vm.tiles = DataService.data;

	} //HomeController()

}()); //IIFE
<|endoftext|>


<commit_before>/**
 * @fileoverview
 * these are lightweight helpers that should not be attached to the element more than once
 */

goog.provide('recoil.ui.HtmlHelper');

goog.require('goog.dom.classlist');
goog.require('recoil.ui.WidgetHelper');

/**
 * @constructor
 * @param {!recoil.ui.WidgetScope} scope gui scope
 */
recoil.ui.HtmlHelper = function(scope) {
    this.scope_ = scope;
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<string>} classesB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.class = function(element, classesB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        if (classesB.good()) {
            goog.dom.classlist.set(element, classesB.get());
        }
    });
    helper.attach(classesB);
    return helper;
};

/**
 * @private
 * @param {number} skip number of args to skip
 * @param {string} elType type of element to create
 * @param {!IArrayLike} args
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createDom_ = function(skip, elType, args) {
    var funcArgs = [elType];
    for (var i = skip; i < args.length; i++) {
        funcArgs.push(args[i]);
    }
    return goog.dom.createDom.apply(null, funcArgs);
};

/**
 * helper function to create make an append function from a create function
 * @template T
 * @param {function(!recoil.frp.Behaviour<T>,(Object|Array<string>|string)=,...(Object|string|Array|NodeList)):!Element} func
 * @param {!IArrayLike} args
 * @return {!Element}
 * @private
 */
recoil.ui.HtmlHelper.prototype.append_ = function(func, args) {
    var funcArgs = [];
    for (var i = 1; i < args.length; i++) {
        funcArgs.push(args[i]);
    }
    var el = func.apply(this, funcArgs);
    goog.dom.append(args[0], el);
    return el;
};

/**
 * @param {!recoil.frp.Behaviour<string>} classesB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createClassDiv = function(classesB, opt_options, var_args) {
    var div = this.createDom_(1, 'div', arguments);
    this.class(div, classesB);
    return div;
};

/**
 * @param {!Node} parent
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendDiv = function(parent, opt_options, var_args) {
    var res = this.createDom_(1, 'div', arguments);
    goog.dom.append(parent, res);
    return res;
};
/**
 * @param {!Node} parent
 * @param {!recoil.frp.Behaviour<string>} classesB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendClassDiv = function(parent, classesB, opt_options, var_args) {
    return this.append_(this.createClassDiv, arguments);
};
/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<string>} innerHtmlB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.innerHtml = function(element, innerHtmlB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        if (innerHtmlB.good()) {
            element.innerHTML = innerHtmlB.get();
        }
        else if (innerHtmlB.metaGet().errors().length > 0) {
            element.innerHTML = innerHtmlB.metaGet().errors().join(',');
        }
    });
    helper.attach(innerHtmlB);
    return helper;
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<string>} innerTextB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.innerText = function(element, innerTextB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        if (innerTextB.good()) {
            element.innerText = innerTextB.get();
        }
        else if (innerTextB.metaGet().errors().length > 0) {
            element.innerText = innerTextB.metaGet().errors().join(',');
        }
    });
    helper.attach(innerTextB);
    return helper;
};

/**
 * @param {!recoil.frp.Behaviour<string>} innerHtmlB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createInnerHtmlDiv = function(innerHtmlB, opt_options, var_args) {
    var div = this.createDom_(1, 'div', arguments);
    this.innerHtml(div, innerHtmlB);
    return div;
};

/**
 * @param {string} type
 * @param {!recoil.frp.Behaviour<string>} innerHtmlB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createInnerHtmlDom = function(type, innerHtmlB, opt_options, var_args) {
    var div = this.createDom_(2, type, arguments);
    this.innerHtml(div, innerHtmlB);
    return div;
};

/**
 * @param {!Node} parent
 * @param {!recoil.frp.Behaviour<?string>|!recoil.frp.Behaviour<string>} innerHtmlB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendInnerHtmlDiv = function(parent, innerHtmlB, opt_options, var_args) {
    return this.append_(this.createInnerHtmlDiv, arguments);
};

/**
 * sets the display to none/undefined depending on {@code showB}
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<boolean>} showB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.show = function(element, showB) {
    var orig = element.style.display;
    orig = orig === 'none' ? undefined : orig;
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        var show = showB.good() && showB.get();
        element.style.display = show ? orig : 'none';
    });
    helper.attach(showB);

    return helper;
};

/**
 * sets the disabled field, I hav called it enabled because I don't like
 * negative logic in code
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<boolean>} enabledB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.enabled = function(element, enabledB) {
    var orig = element.style.display;
    orig = orig === 'none' ? undefined : orig;
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        var disabled = !(enabledB.good() && enabledB.get());
        element.disabled = disabled;
    });
    helper.attach(enabledB);
    return helper;
};

/**
 * @param {!recoil.frp.Behaviour<boolean>} showB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createShowDiv = function(showB, opt_options, var_args) {
    var div = this.createDom_(1, 'div', arguments);
    this.show(div, showB);
    return div;
};

/**
 * @param {!Node} parent
 * @param {!recoil.frp.Behaviour<boolean>} showB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendShowDiv = function(parent, showB, opt_options, var_args) {
    return this.append_(this.createShowDiv, arguments);
};

/**
 * like goog.dom.createDom except it will handle widget, children
 *
 * @param {string} tagName Tag to create.
 * @param {(Object|Array<string>|string)=} opt_attributes If object, then a map
 *     of name-value pairs for attributes. If a string, then this is the
 *     className of the new element. If an array, the elements will be joined
 *     together as the className of the new element.
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element} Reference to a DOM node.
 */

recoil.ui.HtmlHelper.prototype.createDom = function(tagName, opt_attributes, var_args) {
    var parent = goog.dom.createDom(tagName, opt_attributes);
    function childHandler(child) {
        if (child) {
            if (child.getComponent) {
                var comp = child.getComponent();
                comp.render(parent);
            }
            else {
                parent.appendChild(
                goog.isString(child) ? goog.dom.createTextNode(child) : child);
            }
        }
    }
    for (var i = 2; i < arguments.length; i++) {
        var arg = arguments[i];
        if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) {
            // If the argument is a node list, not a real array, use a clone,
            // because forEach can't be used to mutate a NodeList.
            goog.array.forEach(
                goog.dom.isNodeList(arg) ? goog.array.toArray(arg) : arg,
                childHandler);
        } else {
            childHandler(arg);
        }
    }
    return parent;
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onClick = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.CLICK, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragStart = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGSTART, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDrag = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAG, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragEnd = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGEND, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragEnter = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGENTER, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragOver = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGOVER, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragLeave = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGLEAVE, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDrop = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DROP, callbackB);
};

/**
 * @param {!Element} element
 * @param {!goog.events.EventType} event
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onEvent = function(element, event, callbackB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, this, function(helper) {

    });
    var frp = this.scope_.getFrp();
    goog.events.listen(element, event, function(e) {
      // e.stopPropagation();
      // e.preventDefault();
        frp.accessTrans(function() {
            if (callbackB.good()) {
                callbackB.set(e);
            }
        }, callbackB);
    });
    helper.attach(callbackB);

};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<recoil.ui.message.Message>|recoil.ui.message.Message} tooltip
 */
recoil.ui.HtmlHelper.prototype.tooltip = function(element, tooltip) {
    var tooltipEl = null;
    var tooltipB = new recoil.frp.Util(this.scope_.getFrp()).toBehaviour(tooltip);
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, this, function(helper) {

        if (tooltipEl) {
            tooltipEl.dispose();
        }
        tooltipEl = null;
        if (tooltipB.good() && tooltipB.get()) {
            tooltipEl = new goog.ui.Tooltip(element, tooltip.toString());
        }

    }, function() {
        if (tooltipEl) {
            tooltipEl.dispose();
        }
        tooltipEl = null;
    });
    helper.attach(tooltipB);
};
<commit_msg>CT-16775 Added tooltip html helper function<commit_after>/**
 * @fileoverview
 * these are lightweight helpers that should not be attached to the element more than once
 */

goog.provide('recoil.ui.HtmlHelper');

goog.require('goog.dom.classlist');
goog.require('recoil.ui.WidgetHelper');

/**
 * @constructor
 * @param {!recoil.ui.WidgetScope} scope gui scope
 */
recoil.ui.HtmlHelper = function(scope) {
    this.scope_ = scope;
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<string>} classesB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.class = function(element, classesB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        if (classesB.good()) {
            goog.dom.classlist.set(element, classesB.get());
        }
    });
    helper.attach(classesB);
    return helper;
};

/**
 * @private
 * @param {number} skip number of args to skip
 * @param {string} elType type of element to create
 * @param {!IArrayLike} args
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createDom_ = function(skip, elType, args) {
    var funcArgs = [elType];
    for (var i = skip; i < args.length; i++) {
        funcArgs.push(args[i]);
    }
    return goog.dom.createDom.apply(null, funcArgs);
};

/**
 * helper function to create make an append function from a create function
 * @template T
 * @param {function(!recoil.frp.Behaviour<T>,(Object|Array<string>|string)=,...(Object|string|Array|NodeList)):!Element} func
 * @param {!IArrayLike} args
 * @return {!Element}
 * @private
 */
recoil.ui.HtmlHelper.prototype.append_ = function(func, args) {
    var funcArgs = [];
    for (var i = 1; i < args.length; i++) {
        funcArgs.push(args[i]);
    }
    var el = func.apply(this, funcArgs);
    goog.dom.append(args[0], el);
    return el;
};

/**
 * @param {!recoil.frp.Behaviour<string>} classesB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createClassDiv = function(classesB, opt_options, var_args) {
    var div = this.createDom_(1, 'div', arguments);
    this.class(div, classesB);
    return div;
};

/**
 * @param {!Node} parent
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendDiv = function(parent, opt_options, var_args) {
    var res = this.createDom_(1, 'div', arguments);
    goog.dom.append(parent, res);
    return res;
};
/**
 * @param {!Node} parent
 * @param {!recoil.frp.Behaviour<string>} classesB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendClassDiv = function(parent, classesB, opt_options, var_args) {
    return this.append_(this.createClassDiv, arguments);
};
/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<string>} innerHtmlB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.innerHtml = function(element, innerHtmlB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        if (innerHtmlB.good()) {
            element.innerHTML = innerHtmlB.get();
        }
        else if (innerHtmlB.metaGet().errors().length > 0) {
            element.innerHTML = innerHtmlB.metaGet().errors().join(',');
        }
    });
    helper.attach(innerHtmlB);
    return helper;
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<string>} innerTextB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.innerText = function(element, innerTextB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        if (innerTextB.good()) {
            element.innerText = innerTextB.get();
        }
        else if (innerTextB.metaGet().errors().length > 0) {
            element.innerText = innerTextB.metaGet().errors().join(',');
        }
    });
    helper.attach(innerTextB);
    return helper;
};

/**
 * @param {!recoil.frp.Behaviour<string>} innerHtmlB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createInnerHtmlDiv = function(innerHtmlB, opt_options, var_args) {
    var div = this.createDom_(1, 'div', arguments);
    this.innerHtml(div, innerHtmlB);
    return div;
};

/**
 * @param {string} type
 * @param {!recoil.frp.Behaviour<string>} innerHtmlB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createInnerHtmlDom = function(type, innerHtmlB, opt_options, var_args) {
    var div = this.createDom_(2, type, arguments);
    this.innerHtml(div, innerHtmlB);
    return div;
};

/**
 * @param {!Node} parent
 * @param {!recoil.frp.Behaviour<?string>|!recoil.frp.Behaviour<string>} innerHtmlB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendInnerHtmlDiv = function(parent, innerHtmlB, opt_options, var_args) {
    return this.append_(this.createInnerHtmlDiv, arguments);
};

/**
 * sets the display to none/undefined depending on {@code showB}
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<boolean>} showB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.show = function(element, showB) {
    var orig = element.style.display;
    orig = orig === 'none' ? undefined : orig;
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        var show = showB.good() && showB.get();
        element.style.display = show ? orig : 'none';
    });
    helper.attach(showB);

    return helper;
};

/**
 * sets the disabled field, I hav called it enabled because I don't like
 * negative logic in code
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<boolean>} enabledB
 * @return {!recoil.ui.WidgetHelper}
 */
recoil.ui.HtmlHelper.prototype.enabled = function(element, enabledB) {
    var orig = element.style.display;
    orig = orig === 'none' ? undefined : orig;
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, null, function() {
        var disabled = !(enabledB.good() && enabledB.get());
        element.disabled = disabled;
    });
    helper.attach(enabledB);
    return helper;
};

/**
 * @param {!recoil.frp.Behaviour<boolean>} showB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.createShowDiv = function(showB, opt_options, var_args) {
    var div = this.createDom_(1, 'div', arguments);
    this.show(div, showB);
    return div;
};

/**
 * @param {!Node} parent
 * @param {!recoil.frp.Behaviour<boolean>} showB
 * @param {(Object|Array<string>|string)=} opt_options
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element}
 */
recoil.ui.HtmlHelper.prototype.appendShowDiv = function(parent, showB, opt_options, var_args) {
    return this.append_(this.createShowDiv, arguments);
};

/**
 * like goog.dom.createDom except it will handle widget, children
 *
 * @param {string} tagName Tag to create.
 * @param {(Object|Array<string>|string)=} opt_attributes If object, then a map
 *     of name-value pairs for attributes. If a string, then this is the
 *     className of the new element. If an array, the elements will be joined
 *     together as the className of the new element.
 * @param {...(Object|string|Array|NodeList)} var_args Further DOM nodes or
 *     strings for text nodes. If one of the var_args is an array or NodeList,
 *     its elements will be added as childNodes instead.
 * @return {!Element} Reference to a DOM node.
 */

recoil.ui.HtmlHelper.prototype.createDom = function(tagName, opt_attributes, var_args) {
    var parent = goog.dom.createDom(tagName, opt_attributes);
    function childHandler(child) {
        if (child) {
            if (child.getComponent) {
                var comp = child.getComponent();
                comp.render(parent);
            }
            else {
                parent.appendChild(
                goog.isString(child) ? goog.dom.createTextNode(child) : child);
            }
        }
    }
    for (var i = 2; i < arguments.length; i++) {
        var arg = arguments[i];
        if (goog.isArrayLike(arg) && !goog.dom.isNodeLike(arg)) {
            // If the argument is a node list, not a real array, use a clone,
            // because forEach can't be used to mutate a NodeList.
            goog.array.forEach(
                goog.dom.isNodeList(arg) ? goog.array.toArray(arg) : arg,
                childHandler);
        } else {
            childHandler(arg);
        }
    }
    return parent;
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onClick = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.CLICK, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragStart = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGSTART, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDrag = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAG, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragEnd = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGEND, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragEnter = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGENTER, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragOver = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGOVER, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDragLeave = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DRAGLEAVE, callbackB);
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onDrop = function(element, callbackB) {
  this.onEvent(element, goog.events.EventType.DROP, callbackB);
};

/**
 * @param {!Element} element
 * @param {!goog.events.EventType} event
 * @param {!recoil.frp.Behaviour<?>} callbackB
 */
recoil.ui.HtmlHelper.prototype.onEvent = function(element, event, callbackB) {
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, this, function(helper) {

    });
    var frp = this.scope_.getFrp();
    goog.events.listen(element, event, function(e) {
      // e.stopPropagation();
      // e.preventDefault();
        frp.accessTrans(function() {
            if (callbackB.good()) {
                callbackB.set(e);
            }
        }, callbackB);
    });
    helper.attach(callbackB);

};

/**
 * @param {!Element} element
 * @param {string|!recoil.ui.message.Message} tooltip
 */
recoil.ui.HtmlHelper.tooltip = function(element, tooltip) {
    let component = null;
    recoil.frp.DomObserver.instance.listen(element, function(b) {
        if (b) {
            if (!component) {
                component = new goog.ui.Tooltip(element, tooltip.toString());
            }
        }
        else {
            if (component) {
                component.dispose();
                component = null;
            }
        }
    });
};

/**
 * @param {!Element} element
 * @param {!recoil.frp.Behaviour<recoil.ui.message.Message>|recoil.ui.message.Message} tooltip
 */
recoil.ui.HtmlHelper.prototype.tooltip = function(element, tooltip) {
    var tooltipEl = null;
    var tooltipB = new recoil.frp.Util(this.scope_.getFrp()).toBehaviour(tooltip);
    var helper = new recoil.ui.WidgetHelper(this.scope_, element, this, function(helper) {

        if (tooltipEl) {
            tooltipEl.dispose();
        }
        tooltipEl = null;
        if (tooltipB.good() && tooltipB.get()) {
            tooltipEl = new goog.ui.Tooltip(element, tooltip.toString());
        }

    }, function() {
        if (tooltipEl) {
            tooltipEl.dispose();
        }
        tooltipEl = null;
    });
    helper.attach(tooltipB);
};
<|endoftext|>


<commit_before>var EventHandler = (function() {
  var jQueryObject;

  var bindClickEvents = function() {
    $(ChatWindow.chatLog).on('click', ".upvote", upVote);
    ChatWindow.sendButton.on('click', FirebaseModule.sendMessageClickEvent);
  };

  var upVote = function() {
		var incomingUrl = window.location.search;
		jQueryObject = $(this);
		var msg = {
			Content: $(this).parent().text(),
			HiddenUrl: incomingUrl.split('=')[1]
    };
    upVoteAjaxRequest(msg);
  };

  var upVoteAjaxRequest = function(msg) {
    $.ajax({
      method: "POST",
      url: "http://scrawler.azurewebsites.net/chat/savemessage",
      data: msg,
      success: changeMessageClass,
      failure: Errors.ajaxErrorMessage
    });
  };

  var changeMessageClass = function(){
    jQueryObject.removeClass("orange");
    jQueryObject.addClass("red");
  };

  return {
    bindClickEvents: bindClickEvents
  };
})();
<commit_msg>Restricted user voting to single<commit_after>var EventHandler = (function() {
  var jQueryObject;

  var bindClickEvents = function() {
    $(ChatWindow.chatLog).on('click', ".upvote", upVote);
    ChatWindow.sendButton.on('click', FirebaseModule.sendMessageClickEvent);
  };

  var upVote = function() {
    jQueryObject = $(this);
    if (jQueryObject.hasClass("red")) {
      return;
    }
		var incomingUrl = window.location.search;
		var msg = {
			Content: $(this).parent().text(),
			HiddenUrl: incomingUrl.split('=')[1]
    };
    upVoteAjaxRequest(msg);
  };

  var upVoteAjaxRequest = function(msg) {
    $.ajax({
      method: "POST",
      url: "http://scrawler.azurewebsites.net/chat/savemessage",
      data: msg,
      success: changeMessageClass,
      failure: Errors.ajaxErrorMessage
    });
  };

  var changeMessageClass = function(){
    jQueryObject.removeClass("orange");
    jQueryObject.addClass("red");
  };

  return {
    bindClickEvents: bindClickEvents
  };
})();
<|endoftext|>