<commit_before>import React, { Component } from 'react'
import OrganizationAdvisorsTable from 'components/AdvisorReports/OrganizationAdvisorsTable'
import Toolbar from 'components/AdvisorReports/Toolbar'
import _debounce from 'lodash/debounce'
import moment from 'moment'

import API from 'api'

import { connect } from 'react-redux'
import LoaderHOC, {mapDispatchToProps} from 'HOC/LoaderHOC'

const DEFAULT_WEEKS_AGO = 3
const advisorReportsQueryUrl = `/api/reports/insights/advisors` // ?weeksAgo=3 default set at 3 weeks ago
const OrganizationAdvisorsTableWithLoader = connect(null, mapDispatchToProps)(LoaderHOC('isLoading')('data')(OrganizationAdvisorsTable))

class FilterableAdvisorReportsTable extends Component {
    constructor() {
        super()
        this.state = {
            filterText: '',
            export: false,
            data: [],
            isLoading: false,
            selectedData: []
        }
        this.handleFilterTextInput = this.handleFilterTextInput.bind(this)
        this.handleExportButtonClick = this.handleExportButtonClick.bind(this)
        this.handleRowSelection = this.handleRowSelection.bind(this)
    }

    componentDidMount() {
        this.setState( {isLoading: true} )
        let advisorReportsQuery = API.fetch(advisorReportsQueryUrl)
        Promise.resolve(advisorReportsQuery).then(value => {
            this.setState({
                isLoading: false,
                data: value
            })
        })
    }

    handleFilterTextInput(filterText) {
        this.setState({ filterText: filterText })
    }

    handleExportButtonClick() {
        let selectedData = this.state.selectedData
        let allData = this.state.data
        let exportData = (selectedData.length > 0) ? selectedData : allData
        this.downloadCSV( { data: exportData } )
    }

    handleRowSelection(data) {
        this.setState({ selectedData: data })
    }

    getWeekColumns() {
        const dateEnd = moment().startOf('week')
        const dateStart = moment().startOf('week').subtract(DEFAULT_WEEKS_AGO, 'weeks')
        let currentDate = dateStart
        let weekColumns = []
        while(currentDate.isBefore(dateEnd)) {
            weekColumns.push(currentDate.week())
            currentDate = currentDate.add(1, 'weeks')
        }
        return weekColumns
    }

    convertArrayOfObjectsToCSV(args) {
        let result, ctr, csvGroupCols, csvCols, columnDelimiter, lineDelimiter, data

        data = args.data || null
        if (data == null || !data.length) {
            return null
        }

        columnDelimiter = args.columnDelimiter || ','
        lineDelimiter = args.lineDelimiter || '\n'

        let weekColumns = this.getWeekColumns()
        csvGroupCols = ['']
        weekColumns.forEach( (column) => {
            csvGroupCols.push(column)
            csvGroupCols.push('')
        })

        result = ''
        result += csvGroupCols.join(columnDelimiter)
        result += lineDelimiter

        csvCols = ['Organization name']
        weekColumns.forEach( (column) => {
            csvCols.push('Reports submitted')
            csvCols.push('Engagements attended')
        })

        result += csvCols.join(columnDelimiter)
        result += lineDelimiter

        data.forEach( (item) => {
            let stats = item.stats
            ctr = 0
            result += item.organizationshortname
            weekColumns.forEach( (column, index) => {
                if (ctr > 0) result += columnDelimiter

                if (stats[index]) {
                    result += stats[index].nrreportssubmitted
                    result += columnDelimiter
                    result += stats[index].nrengagementsattended
                } else {
                    result += '0,0'
                }
                ctr++
            })
            result += lineDelimiter
        })
        return result
    }

    downloadCSV(args) {
        let filename
        let csv = this.convertArrayOfObjectsToCSV({
            data: args.data
        })
        if (csv == null) return

        filename = args.filename || 'export-advisor-report.csv'
        var blob = new Blob([csv], {type: "text/csv;charset=utf-8;"})

        if (navigator.msSaveBlob) { // IE 10+
            navigator.msSaveBlob(blob, filename)
        } else {
            var link = document.createElement("a")
            if (link.download !== undefined) {
                // feature detection, Browsers that support HTML5 download attribute
                var url = URL.createObjectURL(blob)
                link.setAttribute("href", url)
                link.setAttribute("download", filename)
                link.style = "visibility:hidden"
                document.body.appendChild(link)
                link.click()
                document.body.removeChild(link)
            }
        }
    }

    render() {
        const handleFilterTextInput = _debounce( (filterText) => {this.handleFilterTextInput(filterText) }, 300)
        const columnGroups = this.getWeekColumns()
        return (

                <Toolbar
                    onFilterTextInput={ handleFilterTextInput }
                    onExportButtonClick={ this.handleExportButtonClick } />
                <OrganizationAdvisorsTableWithLoader
                    data={ this.state.data }
                    columnGroups={ columnGroups }
                    filterText={ this.state.filterText }
                    onRowSelection={ this.handleRowSelection }
                    isLoading={ this.state.isLoading } />

        )
    }
}

export default FilterableAdvisorReportsTable
<commit_msg>Add missing comma to CSV export for AdvisorReports<commit_after>import React, { Component } from 'react'
import OrganizationAdvisorsTable from 'components/AdvisorReports/OrganizationAdvisorsTable'
import Toolbar from 'components/AdvisorReports/Toolbar'
import _debounce from 'lodash/debounce'
import moment from 'moment'

import API from 'api'

import { connect } from 'react-redux'
import LoaderHOC, {mapDispatchToProps} from 'HOC/LoaderHOC'

const DEFAULT_WEEKS_AGO = 3
const advisorReportsQueryUrl = `/api/reports/insights/advisors` // ?weeksAgo=3 default set at 3 weeks ago
const OrganizationAdvisorsTableWithLoader = connect(null, mapDispatchToProps)(LoaderHOC('isLoading')('data')(OrganizationAdvisorsTable))

class FilterableAdvisorReportsTable extends Component {
    constructor() {
        super()
        this.state = {
            filterText: '',
            export: false,
            data: [],
            isLoading: false,
            selectedData: []
        }
        this.handleFilterTextInput = this.handleFilterTextInput.bind(this)
        this.handleExportButtonClick = this.handleExportButtonClick.bind(this)
        this.handleRowSelection = this.handleRowSelection.bind(this)
    }

    componentDidMount() {
        this.setState( {isLoading: true} )
        let advisorReportsQuery = API.fetch(advisorReportsQueryUrl)
        Promise.resolve(advisorReportsQuery).then(value => {
            this.setState({
                isLoading: false,
                data: value
            })
        })
    }

    handleFilterTextInput(filterText) {
        this.setState({ filterText: filterText })
    }

    handleExportButtonClick() {
        let selectedData = this.state.selectedData
        let allData = this.state.data
        let exportData = (selectedData.length > 0) ? selectedData : allData
        this.downloadCSV( { data: exportData } )
    }

    handleRowSelection(data) {
        this.setState({ selectedData: data })
    }

    getWeekColumns() {
        const dateEnd = moment().startOf('week')
        const dateStart = moment().startOf('week').subtract(DEFAULT_WEEKS_AGO, 'weeks')
        let currentDate = dateStart
        let weekColumns = []
        while(currentDate.isBefore(dateEnd)) {
            weekColumns.push(currentDate.week())
            currentDate = currentDate.add(1, 'weeks')
        }
        return weekColumns
    }

    convertArrayOfObjectsToCSV(args) {
        let result, csvGroupCols, csvCols, columnDelimiter, lineDelimiter, data

        data = args.data || null
        if (data == null || !data.length) {
            return null
        }

        columnDelimiter = args.columnDelimiter || ','
        lineDelimiter = args.lineDelimiter || '\n'

        let weekColumns = this.getWeekColumns()
        csvGroupCols = ['']
        weekColumns.forEach( (column) => {
            csvGroupCols.push(column)
            csvGroupCols.push('')
        })

        result = ''
        result += csvGroupCols.join(columnDelimiter)
        result += lineDelimiter

        csvCols = ['Organization name']
        weekColumns.forEach( (column) => {
            csvCols.push('Reports submitted')
            csvCols.push('Engagements attended')
        })

        result += csvCols.join(columnDelimiter)
        result += lineDelimiter

        data.forEach( (item) => {
            let stats = item.stats
            result += item.organizationshortname
            weekColumns.forEach( (column, index) => {
                result += columnDelimiter

                if (stats[index]) {
                    result += stats[index].nrreportssubmitted
                    result += columnDelimiter
                    result += stats[index].nrengagementsattended
                } else {
                    result += '0,0'
                }
            })
            result += lineDelimiter
        })
        return result
    }

    downloadCSV(args) {
        let filename
        let csv = this.convertArrayOfObjectsToCSV({
            data: args.data
        })
        if (csv == null) return

        filename = args.filename || 'export-advisor-report.csv'
        var blob = new Blob([csv], {type: "text/csv;charset=utf-8;"})

        if (navigator.msSaveBlob) { // IE 10+
            navigator.msSaveBlob(blob, filename)
        } else {
            var link = document.createElement("a")
            if (link.download !== undefined) {
                // feature detection, Browsers that support HTML5 download attribute
                var url = URL.createObjectURL(blob)
                link.setAttribute("href", url)
                link.setAttribute("download", filename)
                link.style = "visibility:hidden"
                document.body.appendChild(link)
                link.click()
                document.body.removeChild(link)
            }
        }
    }

    render() {
        const handleFilterTextInput = _debounce( (filterText) => {this.handleFilterTextInput(filterText) }, 300)
        const columnGroups = this.getWeekColumns()
        return (

                <Toolbar
                    onFilterTextInput={ handleFilterTextInput }
                    onExportButtonClick={ this.handleExportButtonClick } />
                <OrganizationAdvisorsTableWithLoader
                    data={ this.state.data }
                    columnGroups={ columnGroups }
                    filterText={ this.state.filterText }
                    onRowSelection={ this.handleRowSelection }
                    isLoading={ this.state.isLoading } />

        )
    }
}

export default FilterableAdvisorReportsTable
<|endoftext|>


<commit_before>angular.module('mrlapp.service.AcapelaSpeechGui', [])
.controller('AcapelaSpeechGuiCtrl', ['$scope', '$log', 'mrl', function($scope, $log, mrl) {
    $log.info('AcapelaSpeechGuiCtrl');
    var _self = this;
    var msg = this.msg;

    $scope.text = '';
    $scope.speakingState = '';

    // GOOD TEMPLATE TO FOLLOW
    this.updateState = function(service) {
        $scope.service = service;
        $scope.voice = service.voice;
    }
    ;
    _self.updateState($scope.service);

    // init scope variables
    $scope.text = '';

    this.onMsg = function(inMsg) {
        var data = inMsg.data[0];
        switch (inMsg.method) {
        case 'onState':
            _self.updateState(data);
            $scope.$apply();
            break;
        case 'onStartSpeaking':
            $scope.speakingState = 'speaking';
            $scope.$apply();
            break;
        case 'onEndSpeaking':
            $scope.speakingState = 'finished speaking';
            $scope.$apply();
            break;
        default:
            $log.error("ERROR - unhandled method " + $scope.name + " " + inMsg.method);
            break;
        }
    }
    ;

    //mrl.subscribe($scope.service.name, 'pulse');
    msg.subscribe('publishStartSpeaking');
    msg.subscribe('publishEndSpeaking');
    msg.subscribe(this);
}
]);
<commit_msg>Update AzureTranslatorGui.js<commit_after>angular.module('mrlapp.service.AzureTranslatorGui', [])
.controller('AzureTranslatorGuiCtrl', ['$scope', '$log', 'mrl', function($scope, $log, mrl) {
    $log.info('AzureTranslatorGuiCtrl');
    var _self = this;
    var msg = this.msg;

    $scope.translatedText = '';

    // GOOD TEMPLATE TO FOLLOW
    this.updateState = function(service) {
        $scope.service = service;
        $scope.from = service.fromLanguage;
        $scope.to = service.toLanguage;
    }
    ;
    _self.updateState($scope.service);

    // init scope variables
    $scope.translatedText = '';

    this.onMsg = function(inMsg) {

    }
    ;

    //mrl.subscribe($scope.service.name, 'pulse');
    msg.subscribe(this);
}
]);
<|endoftext|>


<commit_before>iD.ui.MapData = function(context) {
    var key = 'F',
        features = context.features().keys(),
        fills = ['wireframe', 'partial', 'full'],
        fillDefault = context.storage('area-fill') || 'partial',
        fillSelected = fillDefault;

    function map_data(selection) {

        function showsFeature(d) {
            return autoHiddenFeature(d) ? null : !context.features().hidden(d);
        }

        function autoHiddenFeature(d) {
            return context.features().autoHidden(d);
        }

        function clickFeature(d) {
            context.features().toggle(d);
            update();
        }

        function showsFill(d) {
            return fillSelected === d;
        }

        function setFill(d) {
            _.each(fills, function(opt) {
                context.surface().classed('fill-' + opt, Boolean(opt === d));
            });

            fillSelected = d;
            if (d !== 'wireframe') {
                fillDefault = d;
                context.storage('area-fill', d);
            }
            update();
        }

        function clickGpx() {
            context.background().toggleGpxLayer();
            update();
        }

        function clickMapillary() {
            context.background().toggleMapillaryLayer();
            update();
        }

        function drawList(selection, data, type, name, change, active) {
            var items = selection.selectAll('li')
                .data(data);

            //enter
            var enter = items.enter()
                .append('li')
                .attr('class', 'layer')
                .call(bootstrap.tooltip()
                    .html(true)
                    .title(function(d) {
                        var tip = t(name + '.' + d + '.tooltip'),
                            key = (d === 'wireframe' ? 'W' : null);

                        if (name === 'feature' && autoHiddenFeature(d)) {
                            tip += '
' + t('map_data.autohidden') + '
';
                        }
                        return iD.ui.tooltipHtml(tip, key);
                    })
                    .placement('top')
                );

            var label = enter.append('label');

            label.append('input')
                .attr('type', type)
                .attr('name', name)
                .on('change', change);

            label.append('span')
                .text(function(d) { return t(name + '.' + d + '.description'); });

            //update
            items
                .classed('active', active)
                .selectAll('input')
                .property('checked', active);

            if (name === 'feature') {
                items
                    .selectAll('input')
                    .property('disabled', autoHiddenFeature)
                    .property('indeterminate', autoHiddenFeature);
            }

            //exit
            items.exit()
                .remove();
        }

        function update() {
            featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
            fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);

            var hasGpx = context.background().hasGpxLayer(),
                showsGpx = context.background().showsGpxLayer(),
                showsMapillary = context.background().showsMapillaryLayer();

            gpxLayerItem
                .classed('active', showsGpx)
                .selectAll('input')
                .property('disabled', !hasGpx)
                .property('checked', showsGpx);

            mapillaryLayerItem
                .classed('active', showsMapillary)
                .selectAll('input')
                .property('checked', showsMapillary);
        }

        var content = selection.append('div')
                .attr('class', 'fillL map-overlay col3 content hide'),
            tooltip = bootstrap.tooltip()
                .placement('left')
                .html(true)
                .title(iD.ui.tooltipHtml(t('map_data.description'), key));

        function hidePanel() { setVisible(false); }

        function togglePanel() {
            if (d3.event) d3.event.preventDefault();
            tooltip.hide(button);
            setVisible(!button.classed('active'));
        }

        function toggleWireframe() {
            if (d3.event) {
                d3.event.preventDefault();
                d3.event.stopPropagation();
            }
            setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
        }

        function setVisible(show) {
            if (show !== shown) {
                button.classed('active', show);
                shown = show;

                if (show) {
                    selection.on('mousedown.map_data-inside', function() {
                        return d3.event.stopPropagation();
                    });
                    content.style('display', 'block')
                        .style('right', '-300px')
                        .transition()
                        .duration(200)
                        .style('right', '0px');
                } else {
                    content.style('display', 'block')
                        .style('right', '0px')
                        .transition()
                        .duration(200)
                        .style('right', '-300px')
                        .each('end', function() {
                            d3.select(this).style('display', 'none');
                        });
                    selection.on('mousedown.map_data-inside', null);
                }
            }
        }

        var button = selection.append('button')
                .attr('tabindex', -1)
                .on('click', togglePanel)
                .call(tooltip),
            shown = false;

        button.append('span')
            .attr('class', 'icon data light');

        content.append('h4')
            .text(t('map_data.title'));

        // data layers
        content.append('a')
            .text(t('map_data.show_layers'))
            .attr('href', '#')
            .classed('hide-toggle', true)
            .classed('expanded', true)
            .on('click', function() {
                var exp = d3.select(this).classed('expanded');
                layerContainer.style('display', exp ? 'none' : 'block');
                d3.select(this).classed('expanded', !exp);
                d3.event.preventDefault();
            });

        var layerContainer = content.append('div')
            .attr('class', 'filters')
            .style('display', 'block');

        // mapillary
        var mapillaryLayerItem = layerContainer.append('ul')
            .attr('class', 'layer-list')
            .append('li');

        var label = mapillaryLayerItem.append('label')
            .call(bootstrap.tooltip()
                .title(t('mapillary.tooltip'))
                .placement('top'));

        label.append('input')
            .attr('type', 'checkbox')
            .on('change', clickMapillary);

        label.append('span')
            .text(t('mapillary.title'));

        // gpx
        var gpxLayerItem = layerContainer.append('ul')
            .style('display', iD.detect().filedrop ? 'block' : 'none')
            .attr('class', 'layer-list')
            .append('li')
            .classed('layer-toggle-gpx', true);

        gpxLayerItem.append('button')
            .attr('class', 'layer-extent')
            .call(bootstrap.tooltip()
                .title(t('gpx.zoom'))
                .placement('left'))
            .on('click', function() {
                d3.event.preventDefault();
                d3.event.stopPropagation();
                context.background().zoomToGpxLayer();
            })
            .append('span')
            .attr('class', 'icon geolocate');

        gpxLayerItem.append('button')
            .attr('class', 'layer-browse')
            .call(bootstrap.tooltip()
                .title(t('gpx.browse'))
                .placement('left'))
            .on('click', function() {
                d3.select(document.createElement('input'))
                    .attr('type', 'file')
                    .on('change', function() {
                        context.background().gpxLayerFiles(d3.event.target.files);
                    })
                    .node().click();
            })
            .append('span')
            .attr('class', 'icon geocode');

        label = gpxLayerItem.append('label')
            .call(bootstrap.tooltip()
                .title(t('gpx.drag_drop'))
                .placement('top'));

        label.append('input')
            .attr('type', 'checkbox')
            .property('disabled', true)
            .on('change', clickGpx);

        label.append('span')
            .text(t('gpx.local_layer'));

        // area fills
        content.append('a')
            .text(t('map_data.fill_area'))
            .attr('href', '#')
            .classed('hide-toggle', true)
            .classed('expanded', false)
            .on('click', function() {
                var exp = d3.select(this).classed('expanded');
                fillContainer.style('display', exp ? 'none' : 'block');
                d3.select(this).classed('expanded', !exp);
                d3.event.preventDefault();
            });

        var fillContainer = content.append('div')
            .attr('class', 'filters')
            .style('display', 'none');

        var fillList = fillContainer.append('ul')
            .attr('class', 'layer-list');

        // feature filters
        content.append('a')
            .text(t('map_data.show_features'))
            .attr('href', '#')
            .classed('hide-toggle', true)
            .classed('expanded', false)
            .on('click', function() {
                var exp = d3.select(this).classed('expanded');
                featureContainer.style('display', exp ? 'none' : 'block');
                d3.select(this).classed('expanded', !exp);
                d3.event.preventDefault();
            });

        var featureContainer = content.append('div')
            .attr('class', 'filters')
            .style('display', 'none');

        var featureList = featureContainer.append('ul')
            .attr('class', 'layer-list');

        context.features()
            .on('change.map_data-update', update);

        update();
        setFill(fillDefault);

        var keybinding = d3.keybinding('features')
            .on(key, togglePanel)
            .on('W', toggleWireframe);

        // keybinding.on('m', function() {
        //         context.enter(iD.modes.SelectImage(context));
        //     });

        d3.select(document)
            .call(keybinding);

        context.surface().on('mousedown.map_data-outside', hidePanel);
        context.container().on('mousedown.map_data-outside', hidePanel);
    }

    return map_data;
};
<commit_msg>mapdata checkboxes should use features.enabled()<commit_after>iD.ui.MapData = function(context) {
    var key = 'F',
        features = context.features().keys(),
        fills = ['wireframe', 'partial', 'full'],
        fillDefault = context.storage('area-fill') || 'partial',
        fillSelected = fillDefault;

    function map_data(selection) {

        function showsFeature(d) {
            return autoHiddenFeature(d) ? null : context.features().enabled(d);
        }

        function autoHiddenFeature(d) {
            return context.features().autoHidden(d);
        }

        function clickFeature(d) {
            context.features().toggle(d);
            update();
        }

        function showsFill(d) {
            return fillSelected === d;
        }

        function setFill(d) {
            _.each(fills, function(opt) {
                context.surface().classed('fill-' + opt, Boolean(opt === d));
            });

            fillSelected = d;
            if (d !== 'wireframe') {
                fillDefault = d;
                context.storage('area-fill', d);
            }
            update();
        }

        function clickGpx() {
            context.background().toggleGpxLayer();
            update();
        }

        function clickMapillary() {
            context.background().toggleMapillaryLayer();
            update();
        }

        function drawList(selection, data, type, name, change, active) {
            var items = selection.selectAll('li')
                .data(data);

            //enter
            var enter = items.enter()
                .append('li')
                .attr('class', 'layer')
                .call(bootstrap.tooltip()
                    .html(true)
                    .title(function(d) {
                        var tip = t(name + '.' + d + '.tooltip'),
                            key = (d === 'wireframe' ? 'W' : null);

                        if (name === 'feature' && autoHiddenFeature(d)) {
                            tip += '
' + t('map_data.autohidden') + '
';
                        }
                        return iD.ui.tooltipHtml(tip, key);
                    })
                    .placement('top')
                );

            var label = enter.append('label');

            label.append('input')
                .attr('type', type)
                .attr('name', name)
                .on('change', change);

            label.append('span')
                .text(function(d) { return t(name + '.' + d + '.description'); });

            //update
            items
                .classed('active', active)
                .selectAll('input')
                .property('checked', active);

            if (name === 'feature') {
                items
                    .selectAll('input')
                    .property('indeterminate', autoHiddenFeature);
            }

            //exit
            items.exit()
                .remove();
        }

        function update() {
            featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature);
            fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill);

            var hasGpx = context.background().hasGpxLayer(),
                showsGpx = context.background().showsGpxLayer(),
                showsMapillary = context.background().showsMapillaryLayer();

            gpxLayerItem
                .classed('active', showsGpx)
                .selectAll('input')
                .property('disabled', !hasGpx)
                .property('checked', showsGpx);

            mapillaryLayerItem
                .classed('active', showsMapillary)
                .selectAll('input')
                .property('checked', showsMapillary);
        }

        var content = selection.append('div')
                .attr('class', 'fillL map-overlay col3 content hide'),
            tooltip = bootstrap.tooltip()
                .placement('left')
                .html(true)
                .title(iD.ui.tooltipHtml(t('map_data.description'), key));

        function hidePanel() { setVisible(false); }

        function togglePanel() {
            if (d3.event) d3.event.preventDefault();
            tooltip.hide(button);
            setVisible(!button.classed('active'));
        }

        function toggleWireframe() {
            if (d3.event) {
                d3.event.preventDefault();
                d3.event.stopPropagation();
            }
            setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe'));
        }

        function setVisible(show) {
            if (show !== shown) {
                button.classed('active', show);
                shown = show;

                if (show) {
                    selection.on('mousedown.map_data-inside', function() {
                        return d3.event.stopPropagation();
                    });
                    content.style('display', 'block')
                        .style('right', '-300px')
                        .transition()
                        .duration(200)
                        .style('right', '0px');
                } else {
                    content.style('display', 'block')
                        .style('right', '0px')
                        .transition()
                        .duration(200)
                        .style('right', '-300px')
                        .each('end', function() {
                            d3.select(this).style('display', 'none');
                        });
                    selection.on('mousedown.map_data-inside', null);
                }
            }
        }

        var button = selection.append('button')
                .attr('tabindex', -1)
                .on('click', togglePanel)
                .call(tooltip),
            shown = false;

        button.append('span')
            .attr('class', 'icon data light');

        content.append('h4')
            .text(t('map_data.title'));

        // data layers
        content.append('a')
            .text(t('map_data.show_layers'))
            .attr('href', '#')
            .classed('hide-toggle', true)
            .classed('expanded', true)
            .on('click', function() {
                var exp = d3.select(this).classed('expanded');
                layerContainer.style('display', exp ? 'none' : 'block');
                d3.select(this).classed('expanded', !exp);
                d3.event.preventDefault();
            });

        var layerContainer = content.append('div')
            .attr('class', 'filters')
            .style('display', 'block');

        // mapillary
        var mapillaryLayerItem = layerContainer.append('ul')
            .attr('class', 'layer-list')
            .append('li');

        var label = mapillaryLayerItem.append('label')
            .call(bootstrap.tooltip()
                .title(t('mapillary.tooltip'))
                .placement('top'));

        label.append('input')
            .attr('type', 'checkbox')
            .on('change', clickMapillary);

        label.append('span')
            .text(t('mapillary.title'));

        // gpx
        var gpxLayerItem = layerContainer.append('ul')
            .style('display', iD.detect().filedrop ? 'block' : 'none')
            .attr('class', 'layer-list')
            .append('li')
            .classed('layer-toggle-gpx', true);

        gpxLayerItem.append('button')
            .attr('class', 'layer-extent')
            .call(bootstrap.tooltip()
                .title(t('gpx.zoom'))
                .placement('left'))
            .on('click', function() {
                d3.event.preventDefault();
                d3.event.stopPropagation();
                context.background().zoomToGpxLayer();
            })
            .append('span')
            .attr('class', 'icon geolocate');

        gpxLayerItem.append('button')
            .attr('class', 'layer-browse')
            .call(bootstrap.tooltip()
                .title(t('gpx.browse'))
                .placement('left'))
            .on('click', function() {
                d3.select(document.createElement('input'))
                    .attr('type', 'file')
                    .on('change', function() {
                        context.background().gpxLayerFiles(d3.event.target.files);
                    })
                    .node().click();
            })
            .append('span')
            .attr('class', 'icon geocode');

        label = gpxLayerItem.append('label')
            .call(bootstrap.tooltip()
                .title(t('gpx.drag_drop'))
                .placement('top'));

        label.append('input')
            .attr('type', 'checkbox')
            .property('disabled', true)
            .on('change', clickGpx);

        label.append('span')
            .text(t('gpx.local_layer'));

        // area fills
        content.append('a')
            .text(t('map_data.fill_area'))
            .attr('href', '#')
            .classed('hide-toggle', true)
            .classed('expanded', false)
            .on('click', function() {
                var exp = d3.select(this).classed('expanded');
                fillContainer.style('display', exp ? 'none' : 'block');
                d3.select(this).classed('expanded', !exp);
                d3.event.preventDefault();
            });

        var fillContainer = content.append('div')
            .attr('class', 'filters')
            .style('display', 'none');

        var fillList = fillContainer.append('ul')
            .attr('class', 'layer-list');

        // feature filters
        content.append('a')
            .text(t('map_data.show_features'))
            .attr('href', '#')
            .classed('hide-toggle', true)
            .classed('expanded', false)
            .on('click', function() {
                var exp = d3.select(this).classed('expanded');
                featureContainer.style('display', exp ? 'none' : 'block');
                d3.select(this).classed('expanded', !exp);
                d3.event.preventDefault();
            });

        var featureContainer = content.append('div')
            .attr('class', 'filters')
            .style('display', 'none');

        var featureList = featureContainer.append('ul')
            .attr('class', 'layer-list');

        context.features()
            .on('change.map_data-update', update);

        update();
        setFill(fillDefault);

        var keybinding = d3.keybinding('features')
            .on(key, togglePanel)
            .on('W', toggleWireframe);

        // keybinding.on('m', function() {
        //         context.enter(iD.modes.SelectImage(context));
        //     });

        d3.select(document)
            .call(keybinding);

        context.surface().on('mousedown.map_data-outside', hidePanel);
        context.container().on('mousedown.map_data-outside', hidePanel);
    }

    return map_data;
};
<|endoftext|>


<commit_before>google.charts.load('current', {packages: ['corechart','scatter']});

// function to create object of the selected options and call the appropriate function.
function getRequest(){
	var prec = document.getElementById("precision").value;
	var op   = document.getElementById("operations").value;
	switch(op){
		case "addition":
			add(prec);
			//alert("add op");
			break;
		case "subtraction":
			subt(prec);
			//alert("sub op");
			break;
		case "multiplication":
			mult(prec);
			//alert("mul op");
			break;
		case "division":
			divi(prec);
			//alert("div op");
			break;
		default:
			alert("something wrong");
			break;
	}
}
// function to convert (Decimal to Binary) with specify length of the output.
function decbin(dec,length){
	var out = "";
	while(length--)
		out += (dec >> length ) & 1;
	return out;
}

// function to create the simulation of Arithmetics operation ( addition )
function add(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j=0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			// format is:  x index , correct , overflow
			if ((i+j) < range){
				rows[index] = [dictX, dictY, null];
			// else overflow
			}else{
				rows[index] = [dictX, , dictY];
			}
			index += 1;
		}
	}
	//document.getElementById("test1").innerHTML = rows;
	drawChart(rows, ['Overflow']);
}

// function to create the simulation of Arithmetics operation ( subtraction )
function subt(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j=0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			// format is:  x index , correct , overflow
			if ((i-j) >= 0 & (i-j) < range){
				rows[index] = [dictX, dictY, null];
			// else overflow
			}else{
				rows[index] = [dictX, , dictY];
			}
			index += 1;
		}
	}

	drawChart(rows, ['Underflow']);
}

// function to create the simulation of Arithmetics operation ( multiplication )
function mult(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j=0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			// format is:  x index , correct , overflow
			if ((i*j) < range){
				rows[index] = [dictX, dictY, null];
			// else overflow
			}else{
				rows[index] = [dictX, , dictY];
			}
			index += 1;
		}
	}

	drawChart(rows, ['Overflow']);
}

// function to create the simulation of Arithmetics operation ( division )
function divi(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j= 0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			if((i/j) % 1 == 0 ){ // does (1/3) which is 0.33.. mod 1  equal to zero
				rows[index] = [dictX, dictY, null, null];
			// check if is NAN eg. 0/0  or is Infinity(not finite)  eg. 1/0 , 1000/0
			}else if(isNaN(i/j) || !(isFinite(i/j))){
				rows[index] = [dictX, null, null, dictY];
			// else Inexpressible
			}else{
				rows[index] = [dictX, , dictY, null];
			}
			index += 1;
		}
	}
	drawChart(rows, ['Inexpressible', 'Infinity']);
}

function drawChart(obj, arg) {
	// Define the chart to be drawn.
	var data = new google.visualization.DataTable();
	data.addColumn('number', '');
	data.addColumn('number', 'correct');
	if (arg.length == 2){
		// numbers do not divide evenly  (Inexpressible)
		data.addColumn('number', arg[0]);
		// divide by zero
		data.addColumn('number', arg[1]);
	} else{
		data.addColumn('number', arg[0]);
	}

   	data.addRows(obj);
    var options = {
    	chart: {
    		title: ' Plotting the simulation of floating point with Basic Arithmetics',
        	subtitle: 'Based on precision 4 bits'
     	},
     	width: 1050,
     	height: 500,
     	explorer: {
     		actions: ['dragToZoom', 'rightClickToReset'],
        	axis: 'horizontal',
        	keepInBounds: true,
        	maxZoomIn: 4.0
    	},
    };
    var chart = new google.charts.Scatter(document.getElementById('chart_div1'));
    chart.draw(data, google.charts.Scatter.convertOptions(options));

//    var test = chart.getSelection()[0].row;

	// Listen for the 'select' event, and call my function selectHandler() when
	// the user selects something on the chart.

    google.visualization.events.addListener(chart, 'ready', selectHandler);

    function selectHandler(){
    	var selection = chart.getSelection()[0].row;
    	alert("selection")
    }

/*
select
    // This function to get the index of the selected element of chart.
	function selectHandler() {
		var selection = chart.getSelection()[0].row;
		if (selection != null){
			alert(selection);
		}

	};
*/
}

/*
function selectHandler(e) {
  alert('A table row was selected ');//+ chart.getSelection().rows);
}
*/
/*
$('circle').each(function(index,elem){

   alert("cx :"+elem.getAttribute("cx")+"...cy :"+elem.getAttribute("cy")); //using JavaScript

}
*/
/*
// Resize function to diffrent midea
$(window).resize(function(){
  	drawChart();
});

*/<commit_msg>get index<commit_after>google.charts.load('current', {packages: ['corechart','scatter']});

// function to create object of the selected options and call the appropriate function.
function getRequest(){
	var prec = document.getElementById("precision").value;
	var op   = document.getElementById("operations").value;
	switch(op){
		case "addition":
			add(prec);
			//alert("add op");
			break;
		case "subtraction":
			subt(prec);
			//alert("sub op");
			break;
		case "multiplication":
			mult(prec);
			//alert("mul op");
			break;
		case "division":
			divi(prec);
			//alert("div op");
			break;
		default:
			alert("something wrong");
			break;
	}
}
// function to convert (Decimal to Binary) with specify length of the output.
function decbin(dec,length){
	var out = "";
	while(length--)
		out += (dec >> length ) & 1;
	return out;
}

// function to create the simulation of Arithmetics operation ( addition )
function add(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j=0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			// format is:  x index , correct , overflow
			if ((i+j) < range){
				rows[index] = [dictX, dictY, null];
			// else overflow
			}else{
				rows[index] = [dictX, , dictY];
			}
			index += 1;
		}
	}
	//document.getElementById("test1").innerHTML = rows;
	drawChart(rows, ['Overflow']);
}

// function to create the simulation of Arithmetics operation ( subtraction )
function subt(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j=0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			// format is:  x index , correct , overflow
			if ((i-j) >= 0 & (i-j) < range){
				rows[index] = [dictX, dictY, null];
			// else overflow
			}else{
				rows[index] = [dictX, , dictY];
			}
			index += 1;
		}
	}

	drawChart(rows, ['Underflow']);
}

// function to create the simulation of Arithmetics operation ( multiplication )
function mult(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j=0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			// format is:  x index , correct , overflow
			if ((i*j) < range){
				rows[index] = [dictX, dictY, null];
			// else overflow
			}else{
				rows[index] = [dictX, , dictY];
			}
			index += 1;
		}
	}

	drawChart(rows, ['Overflow']);
}

// function to create the simulation of Arithmetics operation ( division )
function divi(obj){
	var prec  = parseInt(obj);
	// range to iteration (loop)
	var range = Math.pow(2, prec);
	var index = 0;
	var rows  = [];
	for (i = 0; i < range; i++){
		var formatX = decbin(i, prec);
		// initialize dictX
		dictX = {};
		// {v:0, f:'0000'}
		var dictX	= {v:i, f: formatX};
		for(j= 0; j < range; j++){
			var formatY = decbin(j, prec);
			// initialize dictY
			var dictY = {};
			// {v:0, f:'0000'}
			var dictY = {v:j, f: formatY};
			// correct logic
			if((i/j) % 1 == 0 ){ // does (1/3) which is 0.33.. mod 1  equal to zero
				rows[index] = [dictX, dictY, null, null];
			// check if is NAN eg. 0/0  or is Infinity(not finite)  eg. 1/0 , 1000/0
			}else if(isNaN(i/j) || !(isFinite(i/j))){
				rows[index] = [dictX, null, null, dictY];
			// else Inexpressible
			}else{
				rows[index] = [dictX, , dictY, null];
			}
			index += 1;
		}
	}
	drawChart(rows, ['Inexpressible', 'Infinity']);
}

function drawChart(obj, arg) {
	// Define the chart to be drawn.
	var data = new google.visualization.DataTable();
	data.addColumn('number', '');
	data.addColumn('number', 'correct');
	if (arg.length == 2){
		// numbers do not divide evenly  (Inexpressible)
		data.addColumn('number', arg[0]);
		// divide by zero
		data.addColumn('number', arg[1]);
	} else{
		data.addColumn('number', arg[0]);
	}

   	data.addRows(obj);
    var options = {
    	chart: {
    		title: ' Plotting the simulation of floating point with Basic Arithmetics',
        	subtitle: 'Based on precision 4 bits'
     	},
     	width: 1050,
     	height: 500,
     	explorer: {
     		actions: ['dragToZoom', 'rightClickToReset'],
        	axis: 'horizontal',
        	keepInBounds: true,
        	maxZoomIn: 4.0
    	},
    };
    var chart = new google.charts.Scatter(document.getElementById('chart_div1'));
    chart.draw(data, google.charts.Scatter.convertOptions(options));

//    var test = chart.getSelection()[0].row;

	// Listen for the 'select' event, and call my function selectHandler() when
	// the user selects something on the chart.

    google.visualization.events.addListener(chart, 'select', selectHandler);

    // This function to get the index of the selected element of chart.
	function selectHandler() {
		var selection = chart.getSelection()[0].row;
		if (selection != null){
			alert(selection);
		}

	};

}

/*
function selectHandler(e) {
  alert('A table row was selected ');//+ chart.getSelection().rows);
}
*/
/*
$('circle').each(function(index,elem){

   alert("cx :"+elem.getAttribute("cx")+"...cy :"+elem.getAttribute("cy")); //using JavaScript

}
*/
/*
// Resize function to diffrent midea
$(window).resize(function(){
  	drawChart();
});

*/<|endoftext|>


<commit_before>///import core
///import plugins/inserthtml.js
///import plugins/undo.js
///import plugins/serialize.js
///commands 粘贴
///commandsName  PastePlain
///commandsTitle  纯文本粘贴模式
/**
 * @description 粘贴
 * @author zhanyi
 */
UE.plugins['paste'] = function () {
    function getClipboardData(callback) {
        var doc = this.document;
        if (doc.getElementById('baidu_pastebin')) {
            return;
        }
        var range = this.selection.getRange(),
            bk = range.createBookmark(),
        //创建剪贴的容器div
            pastebin = doc.createElement('div');
        pastebin.id = 'baidu_pastebin';
        // Safari 要求div必须有内容，才能粘贴内容进来
        browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar));
        doc.body.appendChild(pastebin);
        //trace:717 隐藏的span不能得到top
        //bk.start.innerHTML = ' ';
        bk.start.style.display = '';
        pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
            //要在现在光标平行的位置加入，否则会出现跳动的问题
            domUtils.getXY(bk.start).y + 'px';

        range.selectNodeContents(pastebin).select(true);

        setTimeout(function () {
            if (browser.webkit) {
                for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) {
                    if (domUtils.isEmptyNode(pi)) {
                        domUtils.remove(pi);
                    } else {
                        pastebin = pi;
                        break;
                    }
                }
            }
            try {
                pastebin.parentNode.removeChild(pastebin);
            } catch (e) {
            }
            range.moveToBookmark(bk).select(true);
            callback(pastebin);
        }, 0);
    }

    var me = this;

    me.setOpt({
        retainOnlyLabelPasted : false
    });

    var txtContent, htmlContent, address;

    function getPureHtml(html){
        return html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) {
            tagName = tagName.toLowerCase();
            if ({img: 1}[tagName]) {
                return a;
            }
            attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) {
                if ({
                    'src': 1,
                    'href': 1,
                    'name': 1
                }[atr.toLowerCase()]) {
                    return atr + '=' + val + ' '
                }
                return ''
            });
            if ({
                'span': 1,
                'div': 1
            }[tagName]) {
                return ''
            } else {

                return '<' + b + tagName + ' ' + utils.trim(attrs) + '>'
            }

        });
    }
    function filter(div) {
        var html;
        if (div.firstChild) {
            //去掉cut中添加的边界值
            var nodes = domUtils.getElementsByTagName(div, 'span');
            for (var i = 0, ni; ni = nodes[i++];) {
                if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') {
                    domUtils.remove(ni);
                }
            }

            if (browser.webkit) {

                var brs = div.querySelectorAll('div br');
                for (var i = 0, bi; bi = brs[i++];) {
                    var pN = bi.parentNode;
                    if (pN.tagName == 'DIV' && pN.childNodes.length == 1) {
                        pN.innerHTML = '

';
                        domUtils.remove(pN);
                    }
                }
                var divs = div.querySelectorAll('#baidu_pastebin');
                for (var i = 0, di; di = divs[i++];) {
                    var tmpP = me.document.createElement('p');
                    di.parentNode.insertBefore(tmpP, di);
                    while (di.firstChild) {
                        tmpP.appendChild(di.firstChild);
                    }
                    domUtils.remove(di);
                }

                var metas = div.querySelectorAll('meta');
                for (var i = 0, ci; ci = metas[i++];) {
                    domUtils.remove(ci);
                }

                var brs = div.querySelectorAll('br');
                for (i = 0; ci = brs[i++];) {
                    if (/^apple-/i.test(ci.className)) {
                        domUtils.remove(ci);
                    }
                }
            }
            if (browser.gecko) {
                var dirtyNodes = div.querySelectorAll('[_moz_dirty]');
                for (i = 0; ci = dirtyNodes[i++];) {
                    ci.removeAttribute('_moz_dirty');
                }
            }
            if (!browser.ie) {
                var spans = div.querySelectorAll('span.Apple-style-span');
                for (var i = 0, ci; ci = spans[i++];) {
                    domUtils.remove(ci, true);
                }
            }

            //ie下使用innerHTML会产生多余的\r\n字符，也会产生 这里过滤掉
            html = div.innerHTML;//.replace(/>(?:(\s| )*?)</g,'><');

            //过滤word粘贴过来的冗余属性
            html = UE.filterWord(html);
            //取消了忽略空白的第二个参数，粘贴过来的有些是有空白的，会被套上相关的标签
            var root = UE.htmlparser(html);
            //如果给了过滤规则就先进行过滤
            if (me.options.filterRules) {
                UE.filterNode(root, me.options.filterRules);
            }
            //执行默认的处理
            me.filterInputRule(root);
            //针对chrome的处理
            if (browser.webkit) {
                var br = root.lastChild();
                if (br && br.type == 'element' && br.tagName == 'br') {
                    root.removeChild(br)
                }
                utils.each(me.body.querySelectorAll('div'), function (node) {
                    if (domUtils.isEmptyBlock(node)) {
                        domUtils.remove(node,true)
                    }
                })
            }
            html = {'html': root.toHtml()};
            me.fireEvent('beforepaste', html, root);
            //抢了默认的粘贴，那后边的内容就不执行了，比如表格粘贴
            if(!html.html){
                return;
            }
            root = UE.htmlparser(html.html,true);
            //如果开启了纯文本模式
            if (me.queryCommandState('pasteplain') === 1) {
                me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true);
            } else {
                //文本模式
                UE.filterNode(root, me.options.filterTxtRules);
                txtContent = root.toHtml();
                //完全模式
                htmlContent = html.html;

                address = me.selection.getRange().createAddress(true);
                me.execCommand('insertHtml', me.getOpt('retainOnlyLabelPasted') === true ?  getPureHtml(htmlContent) : htmlContent, true);
            }
            me.fireEvent("afterpaste", html);
        }
    }

    me.addListener('pasteTransfer', function (cmd, plainType) {

        if (address && txtContent && htmlContent && txtContent != htmlContent) {
            var range = me.selection.getRange();
            range.moveToAddress(address, true);

            if (!range.collapsed) {

                while (!domUtils.isBody(range.startContainer)
                    ) {
                    var start = range.startContainer;
                    if(start.nodeType == 1){
                        start = start.childNodes[range.startOffset];
                        if(!start){
                            range.setStartBefore(range.startContainer);
                            continue;
                        }
                        var pre = start.previousSibling;

                        if(pre && pre.nodeType == 3 && new RegExp('^[\n\r\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){
                            range.setStartBefore(pre)
                        }
                    }
                    if(range.startOffset == 0){
                        range.setStartBefore(range.startContainer);
                    }else{
                        break;
                    }

                }
                while (!domUtils.isBody(range.endContainer)
                    ) {
                    var end = range.endContainer;
                    if(end.nodeType == 1){
                        end = end.childNodes[range.endOffset];
                        if(!end){
                            range.setEndAfter(range.endContainer);
                            continue;
                        }
                        var next = end.nextSibling;
                        if(next && next.nodeType == 3 && new RegExp('^[\n\r\t'+domUtils.fillChar+']*$').test(next.nodeValue)){
                            range.setEndAfter(next)
                        }
                    }
                    if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){
                        range.setEndAfter(range.endContainer);
                    }else{
                        break;
                    }

                }

            }

            range.deleteContents();
            range.select(true);
            me.__hasEnterExecCommand = true;
            var html = htmlContent;
            if (plainType === 2 ) {
                html = getPureHtml(html);
            } else if (plainType) {
                html = txtContent;
            }
            me.execCommand('inserthtml', html, true);
            me.__hasEnterExecCommand = false;
            var rng = me.selection.getRange();
            while (!domUtils.isBody(rng.startContainer) && !rng.startOffset &&
                rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length
                ) {
                rng.setStartBefore(rng.startContainer);
            }
            var tmpAddress = rng.createAddress(true);
            address.endAddress = tmpAddress.startAddress;
        }
    });

    me.addListener('ready', function () {
        domUtils.on(me.body, 'cut', function () {
            var range = me.selection.getRange();
            if (!range.collapsed && me.undoManger) {
                me.undoManger.save();
            }
        });

        //ie下beforepaste在点击右键时也会触发，所以用监控键盘才处理
        domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) {
            if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) {
                return;
            }
            getClipboardData.call(me, function (div) {
                filter(div);
            });
        });

    });

    me.commands['paste'] = {
        execCommand: function (cmd) {
            if (browser.ie) {
                getClipboardData.call(me, function (div) {
                    filter(div);
                });
                me.document.execCommand('paste');
            } else {
                alert(me.getLang('copymsg'));
            }
        }
    }
};

<commit_msg>修改粘贴错误提示信息<commit_after>///import core
///import plugins/inserthtml.js
///import plugins/undo.js
///import plugins/serialize.js
///commands 粘贴
///commandsName  PastePlain
///commandsTitle  纯文本粘贴模式
/**
 * @description 粘贴
 * @author zhanyi
 */
UE.plugins['paste'] = function () {
    function getClipboardData(callback) {
        var doc = this.document;
        if (doc.getElementById('baidu_pastebin')) {
            return;
        }
        var range = this.selection.getRange(),
            bk = range.createBookmark(),
        //创建剪贴的容器div
            pastebin = doc.createElement('div');
        pastebin.id = 'baidu_pastebin';
        // Safari 要求div必须有内容，才能粘贴内容进来
        browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar));
        doc.body.appendChild(pastebin);
        //trace:717 隐藏的span不能得到top
        //bk.start.innerHTML = ' ';
        bk.start.style.display = '';
        pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" +
            //要在现在光标平行的位置加入，否则会出现跳动的问题
            domUtils.getXY(bk.start).y + 'px';

        range.selectNodeContents(pastebin).select(true);

        setTimeout(function () {
            if (browser.webkit) {
                for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) {
                    if (domUtils.isEmptyNode(pi)) {
                        domUtils.remove(pi);
                    } else {
                        pastebin = pi;
                        break;
                    }
                }
            }
            try {
                pastebin.parentNode.removeChild(pastebin);
            } catch (e) {
            }
            range.moveToBookmark(bk).select(true);
            callback(pastebin);
        }, 0);
    }

    var me = this;

    me.setOpt({
        retainOnlyLabelPasted : false
    });

    var txtContent, htmlContent, address;

    function getPureHtml(html){
        return html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) {
            tagName = tagName.toLowerCase();
            if ({img: 1}[tagName]) {
                return a;
            }
            attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) {
                if ({
                    'src': 1,
                    'href': 1,
                    'name': 1
                }[atr.toLowerCase()]) {
                    return atr + '=' + val + ' '
                }
                return ''
            });
            if ({
                'span': 1,
                'div': 1
            }[tagName]) {
                return ''
            } else {

                return '<' + b + tagName + ' ' + utils.trim(attrs) + '>'
            }

        });
    }
    function filter(div) {
        var html;
        if (div.firstChild) {
            //去掉cut中添加的边界值
            var nodes = domUtils.getElementsByTagName(div, 'span');
            for (var i = 0, ni; ni = nodes[i++];) {
                if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') {
                    domUtils.remove(ni);
                }
            }

            if (browser.webkit) {

                var brs = div.querySelectorAll('div br');
                for (var i = 0, bi; bi = brs[i++];) {
                    var pN = bi.parentNode;
                    if (pN.tagName == 'DIV' && pN.childNodes.length == 1) {
                        pN.innerHTML = '

';
                        domUtils.remove(pN);
                    }
                }
                var divs = div.querySelectorAll('#baidu_pastebin');
                for (var i = 0, di; di = divs[i++];) {
                    var tmpP = me.document.createElement('p');
                    di.parentNode.insertBefore(tmpP, di);
                    while (di.firstChild) {
                        tmpP.appendChild(di.firstChild);
                    }
                    domUtils.remove(di);
                }

                var metas = div.querySelectorAll('meta');
                for (var i = 0, ci; ci = metas[i++];) {
                    domUtils.remove(ci);
                }

                var brs = div.querySelectorAll('br');
                for (i = 0; ci = brs[i++];) {
                    if (/^apple-/i.test(ci.className)) {
                        domUtils.remove(ci);
                    }
                }
            }
            if (browser.gecko) {
                var dirtyNodes = div.querySelectorAll('[_moz_dirty]');
                for (i = 0; ci = dirtyNodes[i++];) {
                    ci.removeAttribute('_moz_dirty');
                }
            }
            if (!browser.ie) {
                var spans = div.querySelectorAll('span.Apple-style-span');
                for (var i = 0, ci; ci = spans[i++];) {
                    domUtils.remove(ci, true);
                }
            }

            //ie下使用innerHTML会产生多余的\r\n字符，也会产生 这里过滤掉
            html = div.innerHTML;//.replace(/>(?:(\s| )*?)</g,'><');

            //过滤word粘贴过来的冗余属性
            html = UE.filterWord(html);
            //取消了忽略空白的第二个参数，粘贴过来的有些是有空白的，会被套上相关的标签
            var root = UE.htmlparser(html);
            //如果给了过滤规则就先进行过滤
            if (me.options.filterRules) {
                UE.filterNode(root, me.options.filterRules);
            }
            //执行默认的处理
            me.filterInputRule(root);
            //针对chrome的处理
            if (browser.webkit) {
                var br = root.lastChild();
                if (br && br.type == 'element' && br.tagName == 'br') {
                    root.removeChild(br)
                }
                utils.each(me.body.querySelectorAll('div'), function (node) {
                    if (domUtils.isEmptyBlock(node)) {
                        domUtils.remove(node,true)
                    }
                })
            }
            html = {'html': root.toHtml()};
            me.fireEvent('beforepaste', html, root);
            //抢了默认的粘贴，那后边的内容就不执行了，比如表格粘贴
            if(!html.html){
                return;
            }
            root = UE.htmlparser(html.html,true);
            //如果开启了纯文本模式
            if (me.queryCommandState('pasteplain') === 1) {
                me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true);
            } else {
                //文本模式
                UE.filterNode(root, me.options.filterTxtRules);
                txtContent = root.toHtml();
                //完全模式
                htmlContent = html.html;

                address = me.selection.getRange().createAddress(true);
                me.execCommand('insertHtml', me.getOpt('retainOnlyLabelPasted') === true ?  getPureHtml(htmlContent) : htmlContent, true);
            }
            me.fireEvent("afterpaste", html);
        }
    }

    me.addListener('pasteTransfer', function (cmd, plainType) {

        if (address && txtContent && htmlContent && txtContent != htmlContent) {
            var range = me.selection.getRange();
            range.moveToAddress(address, true);

            if (!range.collapsed) {

                while (!domUtils.isBody(range.startContainer)
                    ) {
                    var start = range.startContainer;
                    if(start.nodeType == 1){
                        start = start.childNodes[range.startOffset];
                        if(!start){
                            range.setStartBefore(range.startContainer);
                            continue;
                        }
                        var pre = start.previousSibling;

                        if(pre && pre.nodeType == 3 && new RegExp('^[\n\r\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){
                            range.setStartBefore(pre)
                        }
                    }
                    if(range.startOffset == 0){
                        range.setStartBefore(range.startContainer);
                    }else{
                        break;
                    }

                }
                while (!domUtils.isBody(range.endContainer)
                    ) {
                    var end = range.endContainer;
                    if(end.nodeType == 1){
                        end = end.childNodes[range.endOffset];
                        if(!end){
                            range.setEndAfter(range.endContainer);
                            continue;
                        }
                        var next = end.nextSibling;
                        if(next && next.nodeType == 3 && new RegExp('^[\n\r\t'+domUtils.fillChar+']*$').test(next.nodeValue)){
                            range.setEndAfter(next)
                        }
                    }
                    if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){
                        range.setEndAfter(range.endContainer);
                    }else{
                        break;
                    }

                }

            }

            range.deleteContents();
            range.select(true);
            me.__hasEnterExecCommand = true;
            var html = htmlContent;
            if (plainType === 2 ) {
                html = getPureHtml(html);
            } else if (plainType) {
                html = txtContent;
            }
            me.execCommand('inserthtml', html, true);
            me.__hasEnterExecCommand = false;
            var rng = me.selection.getRange();
            while (!domUtils.isBody(rng.startContainer) && !rng.startOffset &&
                rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length
                ) {
                rng.setStartBefore(rng.startContainer);
            }
            var tmpAddress = rng.createAddress(true);
            address.endAddress = tmpAddress.startAddress;
        }
    });

    me.addListener('ready', function () {
        domUtils.on(me.body, 'cut', function () {
            var range = me.selection.getRange();
            if (!range.collapsed && me.undoManger) {
                me.undoManger.save();
            }
        });

        //ie下beforepaste在点击右键时也会触发，所以用监控键盘才处理
        domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) {
            if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) {
                return;
            }
            getClipboardData.call(me, function (div) {
                filter(div);
            });
        });

    });

    me.commands['paste'] = {
        execCommand: function (cmd) {
            if (browser.ie) {
                getClipboardData.call(me, function (div) {
                    filter(div);
                });
                me.document.execCommand('paste');
            } else {
                alert(me.getLang('copypaste'));
            }
        }
    }
};

<|endoftext|>


<commit_before>XOSTenantSite = XOSModel.extend( {
    listFields: ["name", "allocated"],
    modelName: "tenantSite",
    collectionName: "tenantSites"
});

XOSTenantSiteCollection = XOSCollection.extend( {
    listFields: ["name", "allocated"],
    modelName: "tenantSite",
    collectionName: "tenantSites",

    updateFromSlice: function(slice) {
        var tenantSites = [];
        var id = 0;
        for (siteName in slice.attributes.site_allocation) {
            allocated = slice.attributes.site_allocation[siteName];
            tenantSites.push(new XOSTenantSite( { name: siteName, allocated: allocated, id: id} ));
            id = id + 1;
        }
        for (index in xos.tenantview.models[0].attributes.blessed_site_names) {
            siteName = xos.tenantview.models[0].attributes.blessed_site_names[index];
            if (! (siteName in slice.attributes.site_allocation)) {
                tenantSites.push(new XOSTenantSite( { name: siteName, allocated: 0, id: id} ));
                id = id + 1;
            }
        }
        this.set(tenantSites);
    },
});

XOSTenantButtonView = Marionette.ItemView.extend({
            template: "#xos-tenant-buttons-template",

            events: {"click button.btn-tenant-create": "createClicked",
                     "click button.btn-tenant-delete": "deleteClicked",
                     "click button.btn-tenant-add-user": "addUserClicked",
                     "click button.btn-tenant-save": "saveClicked",
                     },

            createClicked: function(e) {
                     XOSTenantApp.addSlice();
                     },

            deleteClicked: function(e) {
                     XOSTenantApp.deleteSlice(this.options.linkedView.model);
                     },

            addUserClicked: function(e) {
                     },

            saveClicked: function(e) {
                     this.options.linkedView.submitContinueClicked.call(this.options.linkedView, e);
                     },
            });

XOSTenantApp = new XOSApplication({
    logTableId: "#logTable",
    statusMsgId: "#statusMsg",
    hideTabsByDefault: true,
    varName: "XOSTenantApp",
});

XOSTenantApp.addRegions({
    tenantSliceSelector: "#tenantSliceSelector",
    tenantSummary: "#tenantSummary",
    tenantSiteList: "#tenantSiteList",
    tenantButtons: "#tenantButtons",
    tenantAddSliceInterior: "#tenant-addslice-interior",
});

XOSTenantApp.buildViews = function() {
     XOSTenantApp.tenantSites = new XOSTenantSiteCollection();

     tenantSummaryClass = XOSDetailView.extend({template: "#xos-detail-template",
                                                app: XOSTenantApp,
                                                detailFields: ["serviceClass", "image_preference", "network_ports", "mount_data_sets"]});

     XOSTenantApp.tenantSummaryView = tenantSummaryClass;

     tenantAddClass = XOSDetailView.extend({template: "#xos-detail-template",
                                                app: XOSTenantApp,
                                                detailFields: ["name", "description"]});

     XOSTenantApp.tenantAddView = tenantAddClass;

     tenantSiteItemClass = XOSItemView.extend({template: "#xos-listitem-template",
                                               app: XOSTenantApp});

     XOSTenantApp.tenantSiteItemView = tenantSiteItemClass;

     tenantSiteListClass = XOSDataTableView.extend({template: "#xos-list-template",
                                               app: XOSTenantApp,
                                               childView: tenantSiteItemClass,
                                               collection: XOSTenantApp.tenantSites,
                                               title: "sites",
                                               inputType: {allocated: "spinner"},
                                               noDeleteColumn: true,
                                               });

     XOSTenantApp.tenantSiteListView = tenantSiteListClass;

     XOSTenantApp.tenantSliceSelectorView = SliceSelectorView.extend( {
         sliceChanged: function(id) {
             XOSTenantApp.navToSlice(id);
         },
     });

     xos.sites.fetch();
     xos.slicesPlus.fetch();
     xos.tenantview.fetch();
};

make_choices = function(list_of_names, list_of_values) {
    result = [];
    if (!list_of_values) {
        for (index in list_of_names) {
            displayName = list_of_names[index];
            result.push( [displayName, displayName] );
        }
    }
    return result;
};

XOSTenantApp.navToSlice = function(id) {
    XOSTenantApp.viewSlice(xos.slicesPlus.get(id));
};

XOSTenantApp.adjustCollectionField = function(collectionName, id, fieldName, amount) {
    model = XOSTenantApp[collectionName].get(id);
    model.set(fieldName, Math.max(model.get(fieldName) + amount, 0));
};

XOSTenantApp.addSlice = function() {
    var app=this;
    model = new xos.slicesPlus.model({site: xos.tenant().current_user_site_id});
    console.log(model);
    var detailView = new XOSTenantApp.tenantAddView({model: model, collection: xos.slicesPlus});
    detailView.dialog = $("tenant-addslice-dialog");
    app.tenantAddSliceInterior.show(detailView);
    $("#tenant-addslice-dialog").dialog({
       autoOpen: false,
       modal: true,
       width: 640,
       buttons : {
            "Save" : function() {
              var addDialog = this;
              detailView.synchronous = true;
              detailView.afterSave = function() { $(addDialog).dialog("close"); XOSTenantApp.navToSlice(detailView.model.id); }
              detailView.save();
            },
            "Cancel" : function() {
              $(this).dialog("close");
            }
          }
        });
    $("#tenant-addslice-dialog").dialog("open");
};

XOSTenantApp.deleteSlice = function(model) {
    var app=this;
    app.deleteDialog(model, function() { console.log("afterDelete"); app.viewSlice(undefined); });
};

XOSTenantApp.viewSlice = function(model) {
    if (!model && xos.slicesPlus.models.length > 0) {
        model = xos.slicesPlus.models[0];
    }

    sliceSelector = new XOSTenantApp.tenantSliceSelectorView({collection: xos.slicesPlus,
                                                              selectedID: model.id,
                                                             } );
    XOSTenantApp.sliceSelector = sliceSelector;
    XOSTenantApp.tenantSliceSelector.show(sliceSelector);

    tenantSummary = new XOSTenantApp.tenantSummaryView({model: model,
                                                        choices: {mount_data_sets: make_choices(xos.tenantview.models[0].attributes.public_volume_names, null),
                                                                  image_preference: make_choices(xos.tenantview.models[0].attributes.blessed_image_names, null)},
                                                       });
    XOSTenantApp.tenantSummary.show(tenantSummary);

    tenantSites = new XOSTenantSiteCollection();
    tenantSites.updateFromSlice(model);
    XOSTenantApp.tenantSites = tenantSites;

    tenantSiteList = new XOSTenantApp.tenantSiteListView({collection: tenantSites });
    XOSTenantApp.tenantSiteList.show(tenantSiteList);
    // on xos.slicePlus.sort, need to update xostenantapp.tenantSites

    XOSTenantApp.tenantButtons.show( new XOSTenantButtonView( { app: XOSTenantApp,
                                                                linkedView: tenantSummary } ) );
};

XOSTenantApp.startNavigation = function() {
    Backbone.history.start();
    XOSTenantApp.navigationStarted = true;
}

XOSTenantApp.collectionLoadChange = function() {
    stats = xos.getCollectionStatus();

    if (!XOSTenantApp.navigationStarted) {
        if (stats["isLoaded"] + stats["failedLoad"] >= stats["startedLoad"]) {
            XOSTenantApp.viewSlice(undefined);
        } else {
            $("#tenantSummary").html("
Loading...

");
            $("#xos-startup-progress").progressbar({value: stats["completedLoad"], max: stats["startedLoad"]});
        }
    }
};

XOSTenantApp.on("start", function() {
     XOSTenantApp.buildViews();

     // fire it once to initially show the progress bar
     XOSTenantApp.collectionLoadChange();

     // fire it each time the collection load status is updated
     Backbone.on("xoslib:collectionLoadChange", XOSTenantApp.collectionLoadChange);
});

$(document).ready(function(){
    XOSTenantApp.start();
});

<commit_msg>add sanity check; add default_flavors and default_images<commit_after>XOSTenantSite = XOSModel.extend( {
    listFields: ["name", "allocated"],
    modelName: "tenantSite",
    collectionName: "tenantSites"
});

XOSTenantSiteCollection = XOSCollection.extend( {
    listFields: ["name", "allocated"],
    modelName: "tenantSite",
    collectionName: "tenantSites",

    updateFromSlice: function(slice) {
        var tenantSites = [];
        var id = 0;
        for (siteName in slice.attributes.site_allocation) {
            allocated = slice.attributes.site_allocation[siteName];
            tenantSites.push(new XOSTenantSite( { name: siteName, allocated: allocated, id: id} ));
            id = id + 1;
        }
        for (index in xos.tenantview.models[0].attributes.blessed_site_names) {
            siteName = xos.tenantview.models[0].attributes.blessed_site_names[index];
            if (! (siteName in slice.attributes.site_allocation)) {
                tenantSites.push(new XOSTenantSite( { name: siteName, allocated: 0, id: id} ));
                id = id + 1;
            }
        }
        this.set(tenantSites);
    },
});

XOSTenantButtonView = Marionette.ItemView.extend({
            template: "#xos-tenant-buttons-template",

            events: {"click button.btn-tenant-create": "createClicked",
                     "click button.btn-tenant-delete": "deleteClicked",
                     "click button.btn-tenant-add-user": "addUserClicked",
                     "click button.btn-tenant-save": "saveClicked",
                     },

            createClicked: function(e) {
                     XOSTenantApp.addSlice();
                     },

            deleteClicked: function(e) {
                     XOSTenantApp.deleteSlice(this.options.linkedView.model);
                     },

            addUserClicked: function(e) {
                     },

            saveClicked: function(e) {
                     this.options.linkedView.submitContinueClicked.call(this.options.linkedView, e);
                     },
            });

XOSTenantApp = new XOSApplication({
    logTableId: "#logTable",
    statusMsgId: "#statusMsg",
    hideTabsByDefault: true,
    varName: "XOSTenantApp",
});

XOSTenantApp.addRegions({
    tenantSliceSelector: "#tenantSliceSelector",
    tenantSummary: "#tenantSummary",
    tenantSiteList: "#tenantSiteList",
    tenantButtons: "#tenantButtons",
    tenantAddSliceInterior: "#tenant-addslice-interior",
});

XOSTenantApp.buildViews = function() {
     XOSTenantApp.tenantSites = new XOSTenantSiteCollection();

     tenantSummaryClass = XOSDetailView.extend({template: "#xos-detail-template",
                                                app: XOSTenantApp,
                                                detailFields: ["serviceClass", "default_image", "default_flavor", "network_ports", "mount_data_sets"]});

     XOSTenantApp.tenantSummaryView = tenantSummaryClass;

     tenantAddClass = XOSDetailView.extend({template: "#xos-detail-template",
                                                app: XOSTenantApp,
                                                detailFields: ["name", "description"]});

     XOSTenantApp.tenantAddView = tenantAddClass;

     tenantSiteItemClass = XOSItemView.extend({template: "#xos-listitem-template",
                                               app: XOSTenantApp});

     XOSTenantApp.tenantSiteItemView = tenantSiteItemClass;

     tenantSiteListClass = XOSDataTableView.extend({template: "#xos-list-template",
                                               app: XOSTenantApp,
                                               childView: tenantSiteItemClass,
                                               collection: XOSTenantApp.tenantSites,
                                               title: "sites",
                                               inputType: {allocated: "spinner"},
                                               noDeleteColumn: true,
                                               });

     XOSTenantApp.tenantSiteListView = tenantSiteListClass;

     XOSTenantApp.tenantSliceSelectorView = SliceSelectorView.extend( {
         sliceChanged: function(id) {
             XOSTenantApp.navToSlice(id);
         },
     });

     xos.sites.fetch();
     xos.slicesPlus.fetch();
     xos.tenantview.fetch();
};

make_choices = function(list_of_names, list_of_values) {
    result = [];
    if (!list_of_values) {
        for (index in list_of_names) {
            displayName = list_of_names[index];
            result.push( [displayName, displayName] );
        }
    } else {
        for (index in list_of_names) {
            displayName = list_of_names[index];
            id = list_of_values[index];
            result.push( [displayName, id] );
        }
    }
    return result;
};

XOSTenantApp.navToSlice = function(id) {
    XOSTenantApp.viewSlice(xos.slicesPlus.get(id));
};

XOSTenantApp.adjustCollectionField = function(collectionName, id, fieldName, amount) {
    model = XOSTenantApp[collectionName].get(id);
    model.set(fieldName, Math.max(model.get(fieldName) + amount, 0));
};

XOSTenantApp.addSlice = function() {
    var app=this;
    model = new xos.slicesPlus.model({site: xos.tenant().current_user_site_id});
    console.log(model);
    var detailView = new XOSTenantApp.tenantAddView({model: model, collection: xos.slicesPlus});
    detailView.dialog = $("tenant-addslice-dialog");
    app.tenantAddSliceInterior.show(detailView);
    $("#tenant-addslice-dialog").dialog({
       autoOpen: false,
       modal: true,
       width: 640,
       buttons : {
            "Save" : function() {
              var addDialog = this;
              detailView.synchronous = true;
              detailView.afterSave = function() { $(addDialog).dialog("close"); XOSTenantApp.navToSlice(detailView.model.id); }
              detailView.save();
            },
            "Cancel" : function() {
              $(this).dialog("close");
            }
          }
        });
    $("#tenant-addslice-dialog").dialog("open");
};

XOSTenantApp.deleteSlice = function(model) {
    var app=this;
    app.deleteDialog(model, function() { console.log("afterDelete"); app.viewSlice(undefined); });
};

XOSTenantApp.viewSlice = function(model) {
    if (!model && xos.slicesPlus.models.length > 0) {
        model = xos.slicesPlus.models[0];
    }

    sliceSelector = new XOSTenantApp.tenantSliceSelectorView({collection: xos.slicesPlus,
                                                              selectedID: model.id,
                                                             } );
    XOSTenantApp.sliceSelector = sliceSelector;
    XOSTenantApp.tenantSliceSelector.show(sliceSelector);

    tenantSummary = new XOSTenantApp.tenantSummaryView({model: model,
                                                        choices: {mount_data_sets: make_choices(xos.tenant().public_volume_names, null),
                                                                  serviceClass: make_choices(xos.tenant().blessed_service_class_names, xos.tenant().blessed_service_classes),
                                                                  default_image: make_choices(xos.tenant().blessed_image_names, xos.tenant().blessed_image_ids),
                                                                  default_flavor: make_choices(xos.tenant().blessed_flavor_names, xos.tenant().blessed_flavor_ids),},
                                                       });
    XOSTenantApp.tenantSummary.show(tenantSummary);

    tenantSites = new XOSTenantSiteCollection();
    tenantSites.updateFromSlice(model);
    XOSTenantApp.tenantSites = tenantSites;

    tenantSiteList = new XOSTenantApp.tenantSiteListView({collection: tenantSites });
    XOSTenantApp.tenantSiteList.show(tenantSiteList);
    // on xos.slicePlus.sort, need to update xostenantapp.tenantSites

    XOSTenantApp.tenantButtons.show( new XOSTenantButtonView( { app: XOSTenantApp,
                                                                linkedView: tenantSummary } ) );
};

XOSTenantApp.sanityCheck = function() {
    errors = [];
    if (xos.tenant().blessed_service_classes.length == 0) {
        errors.push("no blessed service classes");
    }
    if (xos.tenant().blessed_flavors.length == 0) {
        errors.push("no blessed flavors");
    }
    if (xos.tenant().blessed_images.length == 0) {
        errors.push("no blessed images");
    }
    if (xos.tenant().blessed_sites.length == 0) {
        errors.push("no blessed sites");
    }

    if (errors.length > 0) {
         $("#tenantSummary").html("Tenant view sanity check failed
" + errors.join("
"));
         return false;
    }

    return true;
}

XOSTenantApp.collectionLoadChange = function() {
    stats = xos.getCollectionStatus();

    if (!XOSTenantApp.navigationStarted) {
        if (stats["isLoaded"] + stats["failedLoad"] >= stats["startedLoad"]) {
            if (XOSTenantApp.sanityCheck()) {
                XOSTenantApp.viewSlice(undefined);
            }
        } else {
            $("#tenantSummary").html("
Loading...

");
            $("#xos-startup-progress").progressbar({value: stats["completedLoad"], max: stats["startedLoad"]});
        }
    }
};

XOSTenantApp.on("start", function() {
     XOSTenantApp.buildViews();

     // fire it once to initially show the progress bar
     XOSTenantApp.collectionLoadChange();

     // fire it each time the collection load status is updated
     Backbone.on("xoslib:collectionLoadChange", XOSTenantApp.collectionLoadChange);
});

$(document).ready(function(){
    XOSTenantApp.start();
});

<|endoftext|>