<commit_before>/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as echarts from '../../../echarts';
import * as zrUtil from 'zrender/src/core/util';
import * as eventTool from 'zrender/src/core/event';
import lang from '../../../lang';
import * as featureManager from '../featureManager';

var dataViewLang = lang.toolbox.dataView;

var BLOCK_SPLITER = new Array(60).join('-');
var ITEM_SPLITER = '\t';
/**
 * Group series into two types
 *  1. on category axis, like line, bar
 *  2. others, like scatter, pie
 * @param {module:echarts/model/Global} ecModel
 * @return {Object}
 * @inner
 */
function groupSeries(ecModel) {
    var seriesGroupByCategoryAxis = {};
    var otherSeries = [];
    var meta = [];
    ecModel.eachRawSeries(function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) {
            var baseAxis = coordSys.getBaseAxis();
            if (baseAxis.type === 'category') {
                var key = baseAxis.dim + '_' + baseAxis.index;
                if (!seriesGroupByCategoryAxis[key]) {
                    seriesGroupByCategoryAxis[key] = {
                        categoryAxis: baseAxis,
                        valueAxis: coordSys.getOtherAxis(baseAxis),
                        series: []
                    };
                    meta.push({
                        axisDim: baseAxis.dim,
                        axisIndex: baseAxis.index
                    });
                }
                seriesGroupByCategoryAxis[key].series.push(seriesModel);
            }
            else {
                otherSeries.push(seriesModel);
            }
        }
        else {
            otherSeries.push(seriesModel);
        }
    });

    return {
        seriesGroupByCategoryAxis: seriesGroupByCategoryAxis,
        other: otherSeries,
        meta: meta
    };
}

/**
 * Assemble content of series on cateogory axis
 * @param {Array.<module:echarts/model/Series>} series
 * @return {string}
 * @inner
 */
function assembleSeriesWithCategoryAxis(series) {
    var tables = [];
    zrUtil.each(series, function (group, key) {
        var categoryAxis = group.categoryAxis;
        var valueAxis = group.valueAxis;
        var valueAxisDim = valueAxis.dim;

        var headers = [' '].concat(zrUtil.map(group.series, function (series) {
            return series.name;
        }));
        var columns = [categoryAxis.model.getCategories()];
        zrUtil.each(group.series, function (series) {
            columns.push(series.getRawData().mapArray(valueAxisDim, function (val) {
                return val;
            }));
        });
        // Assemble table content
        var lines = [headers.join(ITEM_SPLITER)];
        for (var i = 0; i < columns[0].length; i++) {
            var items = [];
            for (var j = 0; j < columns.length; j++) {
                items.push(columns[j][i]);
            }
            lines.push(items.join(ITEM_SPLITER));
        }
        tables.push(lines.join('\n'));
    });
    return tables.join('\n\n' + BLOCK_SPLITER + '\n\n');
}

/**
 * Assemble content of other series
 * @param {Array.<module:echarts/model/Series>} series
 * @return {string}
 * @inner
 */
function assembleOtherSeries(series) {
    return zrUtil.map(series, function (series) {
        var data = series.getRawData();
        var lines = [series.name];
        var vals = [];
        data.each(data.dimensions, function () {
            var argLen = arguments.length;
            var dataIndex = arguments[argLen - 1];
            var name = data.getName(dataIndex);
            for (var i = 0; i < argLen - 1; i++) {
                vals[i] = arguments[i];
            }
            lines.push((name ? (name + ITEM_SPLITER) : '') + vals.join(ITEM_SPLITER));
        });
        return lines.join('\n');
    }).join('\n\n' + BLOCK_SPLITER + '\n\n');
}

/**
 * @param {module:echarts/model/Global}
 * @return {Object}
 * @inner
 */
function getContentFromModel(ecModel) {

    var result = groupSeries(ecModel);

    return {
        value: zrUtil.filter([
                assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis),
                assembleOtherSeries(result.other)
            ], function (str) {
                return str.replace(/[\n\t\s]/g, '');
            }).join('\n\n' + BLOCK_SPLITER + '\n\n'),

        meta: result.meta
    };
}

function trim(str) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
/**
 * If a block is tsv format
 */
function isTSVFormat(block) {
    // Simple method to find out if a block is tsv format
    var firstLine = block.slice(0, block.indexOf('\n'));
    if (firstLine.indexOf(ITEM_SPLITER) >= 0) {
        return true;
    }
}

var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g');
/**
 * @param {string} tsv
 * @return {Object}
 */
function parseTSVContents(tsv) {
    var tsvLines = tsv.split(/\n+/g);
    var headers = trim(tsvLines.shift()).split(itemSplitRegex);

    var categories = [];
    var series = zrUtil.map(headers, function (header) {
        return {
            name: header,
            data: []
        };
    });
    for (var i = 0; i < tsvLines.length; i++) {
        var items = trim(tsvLines[i]).split(itemSplitRegex);
        categories.push(items.shift());
        for (var j = 0; j < items.length; j++) {
            series[j] && (series[j].data[i] = items[j]);
        }
    }
    return {
        series: series,
        categories: categories
    };
}

/**
 * @param {string} str
 * @return {Array.<Object>}
 * @inner
 */
function parseListContents(str) {
    var lines = str.split(/\n+/g);
    var seriesName = trim(lines.shift());

    var data = [];
    for (var i = 0; i < lines.length; i++) {
        // if line is empty, ignore it.
        // there is a case that a user forgot to delete `\n`.
        var line = trim(lines[i]);
        if (!line) {
            continue;
        }
        var items = line.split(itemSplitRegex);
        var name = '';
        var value;
        var hasName = false;
        if (isNaN(items[0])) { // First item is name
            hasName = true;
            name = items[0];
            items = items.slice(1);
            data[i] = {
                name: name,
                value: []
            };
            value = data[i].value;
        }
        else {
            value = data[i] = [];
        }
        for (var j = 0; j < items.length; j++) {
            value.push(+items[j]);
        }
        if (value.length === 1) {
            hasName ? (data[i].value = value[0]) : (data[i] = value[0]);
        }
    }

    return {
        name: seriesName,
        data: data
    };
}

/**
 * @param {string} str
 * @param {Array.<Object>} blockMetaList
 * @return {Object}
 * @inner
 */
function parseContents(str, blockMetaList) {
    var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));
    var newOption = {
        series: []
    };
    zrUtil.each(blocks, function (block, idx) {
        if (isTSVFormat(block)) {
            var result = parseTSVContents(block);
            var blockMeta = blockMetaList[idx];
            var axisKey = blockMeta.axisDim + 'Axis';

            if (blockMeta) {
                newOption[axisKey] = newOption[axisKey] || [];
                newOption[axisKey][blockMeta.axisIndex] = {
                    data: result.categories
                };
                newOption.series = newOption.series.concat(result.series);
            }
        }
        else {
            var result = parseListContents(block);
            newOption.series.push(result);
        }
    });
    return newOption;
}

/**
 * @alias {module:echarts/component/toolbox/feature/DataView}
 * @constructor
 * @param {module:echarts/model/Model} model
 */
function DataView(model) {

    this._dom = null;

    this.model = model;
}

DataView.defaultOption = {
    show: true,
    readOnly: false,
    optionToContent: null,
    contentToOption: null,

    icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',
    title: zrUtil.clone(dataViewLang.title),
    lang: zrUtil.clone(dataViewLang.lang),
    backgroundColor: '#fff',
    textColor: '#000',
    textareaColor: '#fff',
    textareaBorderColor: '#333',
    buttonColor: '#c23531',
    buttonTextColor: '#fff'
};

DataView.prototype.onclick = function (ecModel, api) {
    var container = api.getDom();
    var model = this.model;
    if (this._dom) {
        container.removeChild(this._dom);
    }
    var root = document.createElement('div');
    root.style.cssText = 'position:absolute;left:5px;top:5px;bottom:5px;right:5px;';
    root.style.backgroundColor = model.get('backgroundColor') || '#fff';

    // Create elements
    var header = document.createElement('h4');
    var lang = model.get('lang') || [];
    header.innerHTML = lang[0] || model.get('title');
    header.style.cssText = 'margin: 10px 20px;';
    header.style.color = model.get('textColor');

    var viewMain = document.createElement('div');
    var textarea = document.createElement('textarea');
    viewMain.style.cssText = 'display:block;width:100%;overflow:auto;';

    var optionToContent = model.get('optionToContent');
    var contentToOption = model.get('contentToOption');
    var result = getContentFromModel(ecModel);
    if (typeof optionToContent === 'function') {
        var htmlOrDom = optionToContent(api.getOption());
        if (typeof htmlOrDom === 'string') {
            viewMain.innerHTML = htmlOrDom;
        }
        else if (zrUtil.isDom(htmlOrDom)) {
            viewMain.appendChild(htmlOrDom);
        }
    }
    else {
        // Use default textarea
        viewMain.appendChild(textarea);
        textarea.readOnly = model.get('readOnly');
        textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;';
        textarea.style.color = model.get('textColor');
        textarea.style.borderColor = model.get('textareaBorderColor');
        textarea.style.backgroundColor = model.get('textareaColor');
        textarea.value = result.value;
    }

    var blockMetaList = result.meta;

    var buttonContainer = document.createElement('div');
    buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;';

    var buttonStyle = 'float:right;margin-right:20px;border:none;'
        + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
    var closeButton = document.createElement('div');
    var refreshButton = document.createElement('div');

    buttonStyle += ';background-color:' + model.get('buttonColor');
    buttonStyle += ';color:' + model.get('buttonTextColor');

    var self = this;

    function close() {
        container.removeChild(root);
        self._dom = null;
    }
    eventTool.addEventListener(closeButton, 'click', close);

    eventTool.addEventListener(refreshButton, 'click', function () {
        var newOption;
        try {
            if (typeof contentToOption === 'function') {
                newOption = contentToOption(viewMain, api.getOption());
            }
            else {
                newOption = parseContents(textarea.value, blockMetaList);
            }
        }
        catch (e) {
            close();
            throw new Error('Data view format error ' + e);
        }
        if (newOption) {
            api.dispatchAction({
                type: 'changeDataView',
                newOption: newOption
            });
        }

        close();
    });

    closeButton.innerHTML = lang[1];
    refreshButton.innerHTML = lang[2];
    refreshButton.style.cssText = buttonStyle;
    closeButton.style.cssText = buttonStyle;

    !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
    buttonContainer.appendChild(closeButton);

    root.appendChild(header);
    root.appendChild(viewMain);
    root.appendChild(buttonContainer);

    viewMain.style.height = (container.clientHeight - 80) + 'px';

    container.appendChild(root);
    this._dom = root;
};

DataView.prototype.remove = function (ecModel, api) {
    this._dom && api.getDom().removeChild(this._dom);
};

DataView.prototype.dispose = function (ecModel, api) {
    this.remove(ecModel, api);
};

/**
 * @inner
 */
function tryMergeDataOption(newData, originalData) {
    return zrUtil.map(newData, function (newVal, idx) {
        var original = originalData && originalData[idx];
        if (zrUtil.isObject(original) && !zrUtil.isArray(original)) {
            var _newVal;
            if (zrUtil.isArray(newVal) || zrUtil.isObject(newVal)) {
                _newVal = newVal;
            }
            else {
                _newVal = {
                    value: newVal
                };
            }
            // Original data has option
            return zrUtil.defaults(_newVal, original);
        }
        else {
            return newVal;
        }
    });
}

featureManager.register('dataView', DataView);

echarts.registerAction({
    type: 'changeDataView',
    event: 'dataViewChanged',
    update: 'prepareAndUpdate'
}, function (payload, ecModel) {
    var newSeriesOptList = [];
    zrUtil.each(payload.newOption.series, function (seriesOpt) {
        var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];
        if (!seriesModel) {
            // New created series
            // Geuss the series type
            newSeriesOptList.push(zrUtil.extend({
                // Default is scatter
                type: 'scatter'
            }, seriesOpt));
        }
        else {
            var originalData = seriesModel.get('data');
            newSeriesOptList.push({
                name: seriesOpt.name,
                data: tryMergeDataOption(seriesOpt.data, originalData)
            });
        }
    });

    ecModel.mergeOption(zrUtil.defaults({
        series: newSeriesOptList
    }, payload.newOption));
});

export default DataView;
<commit_msg>fix(dataview): tweak `tryMergeDataOption`.<commit_after>/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as echarts from '../../../echarts';
import * as zrUtil from 'zrender/src/core/util';
import * as eventTool from 'zrender/src/core/event';
import lang from '../../../lang';
import * as featureManager from '../featureManager';

var dataViewLang = lang.toolbox.dataView;

var BLOCK_SPLITER = new Array(60).join('-');
var ITEM_SPLITER = '\t';
/**
 * Group series into two types
 *  1. on category axis, like line, bar
 *  2. others, like scatter, pie
 * @param {module:echarts/model/Global} ecModel
 * @return {Object}
 * @inner
 */
function groupSeries(ecModel) {
    var seriesGroupByCategoryAxis = {};
    var otherSeries = [];
    var meta = [];
    ecModel.eachRawSeries(function (seriesModel) {
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && (coordSys.type === 'cartesian2d' || coordSys.type === 'polar')) {
            var baseAxis = coordSys.getBaseAxis();
            if (baseAxis.type === 'category') {
                var key = baseAxis.dim + '_' + baseAxis.index;
                if (!seriesGroupByCategoryAxis[key]) {
                    seriesGroupByCategoryAxis[key] = {
                        categoryAxis: baseAxis,
                        valueAxis: coordSys.getOtherAxis(baseAxis),
                        series: []
                    };
                    meta.push({
                        axisDim: baseAxis.dim,
                        axisIndex: baseAxis.index
                    });
                }
                seriesGroupByCategoryAxis[key].series.push(seriesModel);
            }
            else {
                otherSeries.push(seriesModel);
            }
        }
        else {
            otherSeries.push(seriesModel);
        }
    });

    return {
        seriesGroupByCategoryAxis: seriesGroupByCategoryAxis,
        other: otherSeries,
        meta: meta
    };
}

/**
 * Assemble content of series on cateogory axis
 * @param {Array.<module:echarts/model/Series>} series
 * @return {string}
 * @inner
 */
function assembleSeriesWithCategoryAxis(series) {
    var tables = [];
    zrUtil.each(series, function (group, key) {
        var categoryAxis = group.categoryAxis;
        var valueAxis = group.valueAxis;
        var valueAxisDim = valueAxis.dim;

        var headers = [' '].concat(zrUtil.map(group.series, function (series) {
            return series.name;
        }));
        var columns = [categoryAxis.model.getCategories()];
        zrUtil.each(group.series, function (series) {
            columns.push(series.getRawData().mapArray(valueAxisDim, function (val) {
                return val;
            }));
        });
        // Assemble table content
        var lines = [headers.join(ITEM_SPLITER)];
        for (var i = 0; i < columns[0].length; i++) {
            var items = [];
            for (var j = 0; j < columns.length; j++) {
                items.push(columns[j][i]);
            }
            lines.push(items.join(ITEM_SPLITER));
        }
        tables.push(lines.join('\n'));
    });
    return tables.join('\n\n' + BLOCK_SPLITER + '\n\n');
}

/**
 * Assemble content of other series
 * @param {Array.<module:echarts/model/Series>} series
 * @return {string}
 * @inner
 */
function assembleOtherSeries(series) {
    return zrUtil.map(series, function (series) {
        var data = series.getRawData();
        var lines = [series.name];
        var vals = [];
        data.each(data.dimensions, function () {
            var argLen = arguments.length;
            var dataIndex = arguments[argLen - 1];
            var name = data.getName(dataIndex);
            for (var i = 0; i < argLen - 1; i++) {
                vals[i] = arguments[i];
            }
            lines.push((name ? (name + ITEM_SPLITER) : '') + vals.join(ITEM_SPLITER));
        });
        return lines.join('\n');
    }).join('\n\n' + BLOCK_SPLITER + '\n\n');
}

/**
 * @param {module:echarts/model/Global}
 * @return {Object}
 * @inner
 */
function getContentFromModel(ecModel) {

    var result = groupSeries(ecModel);

    return {
        value: zrUtil.filter([
                assembleSeriesWithCategoryAxis(result.seriesGroupByCategoryAxis),
                assembleOtherSeries(result.other)
            ], function (str) {
                return str.replace(/[\n\t\s]/g, '');
            }).join('\n\n' + BLOCK_SPLITER + '\n\n'),

        meta: result.meta
    };
}

function trim(str) {
    return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
/**
 * If a block is tsv format
 */
function isTSVFormat(block) {
    // Simple method to find out if a block is tsv format
    var firstLine = block.slice(0, block.indexOf('\n'));
    if (firstLine.indexOf(ITEM_SPLITER) >= 0) {
        return true;
    }
}

var itemSplitRegex = new RegExp('[' + ITEM_SPLITER + ']+', 'g');
/**
 * @param {string} tsv
 * @return {Object}
 */
function parseTSVContents(tsv) {
    var tsvLines = tsv.split(/\n+/g);
    var headers = trim(tsvLines.shift()).split(itemSplitRegex);

    var categories = [];
    var series = zrUtil.map(headers, function (header) {
        return {
            name: header,
            data: []
        };
    });
    for (var i = 0; i < tsvLines.length; i++) {
        var items = trim(tsvLines[i]).split(itemSplitRegex);
        categories.push(items.shift());
        for (var j = 0; j < items.length; j++) {
            series[j] && (series[j].data[i] = items[j]);
        }
    }
    return {
        series: series,
        categories: categories
    };
}

/**
 * @param {string} str
 * @return {Array.<Object>}
 * @inner
 */
function parseListContents(str) {
    var lines = str.split(/\n+/g);
    var seriesName = trim(lines.shift());

    var data = [];
    for (var i = 0; i < lines.length; i++) {
        // if line is empty, ignore it.
        // there is a case that a user forgot to delete `\n`.
        var line = trim(lines[i]);
        if (!line) {
            continue;
        }
        var items = line.split(itemSplitRegex);
        var name = '';
        var value;
        var hasName = false;
        if (isNaN(items[0])) { // First item is name
            hasName = true;
            name = items[0];
            items = items.slice(1);
            data[i] = {
                name: name,
                value: []
            };
            value = data[i].value;
        }
        else {
            value = data[i] = [];
        }
        for (var j = 0; j < items.length; j++) {
            value.push(+items[j]);
        }
        if (value.length === 1) {
            hasName ? (data[i].value = value[0]) : (data[i] = value[0]);
        }
    }

    return {
        name: seriesName,
        data: data
    };
}

/**
 * @param {string} str
 * @param {Array.<Object>} blockMetaList
 * @return {Object}
 * @inner
 */
function parseContents(str, blockMetaList) {
    var blocks = str.split(new RegExp('\n*' + BLOCK_SPLITER + '\n*', 'g'));
    var newOption = {
        series: []
    };
    zrUtil.each(blocks, function (block, idx) {
        if (isTSVFormat(block)) {
            var result = parseTSVContents(block);
            var blockMeta = blockMetaList[idx];
            var axisKey = blockMeta.axisDim + 'Axis';

            if (blockMeta) {
                newOption[axisKey] = newOption[axisKey] || [];
                newOption[axisKey][blockMeta.axisIndex] = {
                    data: result.categories
                };
                newOption.series = newOption.series.concat(result.series);
            }
        }
        else {
            var result = parseListContents(block);
            newOption.series.push(result);
        }
    });
    return newOption;
}

/**
 * @alias {module:echarts/component/toolbox/feature/DataView}
 * @constructor
 * @param {module:echarts/model/Model} model
 */
function DataView(model) {

    this._dom = null;

    this.model = model;
}

DataView.defaultOption = {
    show: true,
    readOnly: false,
    optionToContent: null,
    contentToOption: null,

    icon: 'M17.5,17.3H33 M17.5,17.3H33 M45.4,29.5h-28 M11.5,2v56H51V14.8L38.4,2H11.5z M38.4,2.2v12.7H51 M45.4,41.7h-28',
    title: zrUtil.clone(dataViewLang.title),
    lang: zrUtil.clone(dataViewLang.lang),
    backgroundColor: '#fff',
    textColor: '#000',
    textareaColor: '#fff',
    textareaBorderColor: '#333',
    buttonColor: '#c23531',
    buttonTextColor: '#fff'
};

DataView.prototype.onclick = function (ecModel, api) {
    var container = api.getDom();
    var model = this.model;
    if (this._dom) {
        container.removeChild(this._dom);
    }
    var root = document.createElement('div');
    root.style.cssText = 'position:absolute;left:5px;top:5px;bottom:5px;right:5px;';
    root.style.backgroundColor = model.get('backgroundColor') || '#fff';

    // Create elements
    var header = document.createElement('h4');
    var lang = model.get('lang') || [];
    header.innerHTML = lang[0] || model.get('title');
    header.style.cssText = 'margin: 10px 20px;';
    header.style.color = model.get('textColor');

    var viewMain = document.createElement('div');
    var textarea = document.createElement('textarea');
    viewMain.style.cssText = 'display:block;width:100%;overflow:auto;';

    var optionToContent = model.get('optionToContent');
    var contentToOption = model.get('contentToOption');
    var result = getContentFromModel(ecModel);
    if (typeof optionToContent === 'function') {
        var htmlOrDom = optionToContent(api.getOption());
        if (typeof htmlOrDom === 'string') {
            viewMain.innerHTML = htmlOrDom;
        }
        else if (zrUtil.isDom(htmlOrDom)) {
            viewMain.appendChild(htmlOrDom);
        }
    }
    else {
        // Use default textarea
        viewMain.appendChild(textarea);
        textarea.readOnly = model.get('readOnly');
        textarea.style.cssText = 'width:100%;height:100%;font-family:monospace;font-size:14px;line-height:1.6rem;';
        textarea.style.color = model.get('textColor');
        textarea.style.borderColor = model.get('textareaBorderColor');
        textarea.style.backgroundColor = model.get('textareaColor');
        textarea.value = result.value;
    }

    var blockMetaList = result.meta;

    var buttonContainer = document.createElement('div');
    buttonContainer.style.cssText = 'position:absolute;bottom:0;left:0;right:0;';

    var buttonStyle = 'float:right;margin-right:20px;border:none;'
        + 'cursor:pointer;padding:2px 5px;font-size:12px;border-radius:3px';
    var closeButton = document.createElement('div');
    var refreshButton = document.createElement('div');

    buttonStyle += ';background-color:' + model.get('buttonColor');
    buttonStyle += ';color:' + model.get('buttonTextColor');

    var self = this;

    function close() {
        container.removeChild(root);
        self._dom = null;
    }
    eventTool.addEventListener(closeButton, 'click', close);

    eventTool.addEventListener(refreshButton, 'click', function () {
        var newOption;
        try {
            if (typeof contentToOption === 'function') {
                newOption = contentToOption(viewMain, api.getOption());
            }
            else {
                newOption = parseContents(textarea.value, blockMetaList);
            }
        }
        catch (e) {
            close();
            throw new Error('Data view format error ' + e);
        }
        if (newOption) {
            api.dispatchAction({
                type: 'changeDataView',
                newOption: newOption
            });
        }

        close();
    });

    closeButton.innerHTML = lang[1];
    refreshButton.innerHTML = lang[2];
    refreshButton.style.cssText = buttonStyle;
    closeButton.style.cssText = buttonStyle;

    !model.get('readOnly') && buttonContainer.appendChild(refreshButton);
    buttonContainer.appendChild(closeButton);

    root.appendChild(header);
    root.appendChild(viewMain);
    root.appendChild(buttonContainer);

    viewMain.style.height = (container.clientHeight - 80) + 'px';

    container.appendChild(root);
    this._dom = root;
};

DataView.prototype.remove = function (ecModel, api) {
    this._dom && api.getDom().removeChild(this._dom);
};

DataView.prototype.dispose = function (ecModel, api) {
    this.remove(ecModel, api);
};

/**
 * @inner
 */
function tryMergeDataOption(newData, originalData) {
    return zrUtil.map(newData, function (newVal, idx) {
        var original = originalData && originalData[idx];
        if (zrUtil.isObject(original) && !zrUtil.isArray(original)) {
            var newValIsObject = zrUtil.isObject(newVal) && !zrUtil.isArray(newVal);
            if (!newValIsObject) {
                newVal = {
                    value: newVal
                };
            }
            // original data has name but new data has no name
            if (original.name != null && newVal.name == null) {
                delete original.name;
            }
            // Original data has option
            return zrUtil.defaults(newVal, original);
        }
        else {
            return newVal;
        }
    });
}

featureManager.register('dataView', DataView);

echarts.registerAction({
    type: 'changeDataView',
    event: 'dataViewChanged',
    update: 'prepareAndUpdate'
}, function (payload, ecModel) {
    var newSeriesOptList = [];
    zrUtil.each(payload.newOption.series, function (seriesOpt) {
        var seriesModel = ecModel.getSeriesByName(seriesOpt.name)[0];
        if (!seriesModel) {
            // New created series
            // Geuss the series type
            newSeriesOptList.push(zrUtil.extend({
                // Default is scatter
                type: 'scatter'
            }, seriesOpt));
        }
        else {
            var originalData = seriesModel.get('data');
            newSeriesOptList.push({
                name: seriesOpt.name,
                data: tryMergeDataOption(seriesOpt.data, originalData)
            });
        }
    });

    ecModel.mergeOption(zrUtil.defaults({
        series: newSeriesOptList
    }, payload.newOption));
});

export default DataView;
<|endoftext|>


<commit_before>/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import React, { PropTypes, Component } from 'react';
import styles from './ContactPage.css';
import withStyles from '../../decorators/withStyles';

@withStyles(styles)
class ContactPage extends Component {

  static contextTypes = {
    onSetTitle: PropTypes.func.isRequired,
  };

  render() {
    const title = 'Contact Me';
    this.context.onSetTitle(title);
    return (

{title}

...

    );
  }

}

export default ContactPage;
<commit_msg>Another small change to the contact page component<commit_after>/*! React Starter Kit | MIT License | http://www.reactstarterkit.com/ */

import React, { PropTypes, Component } from 'react';
import styles from './ContactPage.css';
import withStyles from '../../decorators/withStyles';

@withStyles(styles)
class ContactPage extends Component {

  static contextTypes = {
    onSetTitle: PropTypes.func.isRequired,
  };

  render() {
    const title = 'Contact Us';
    this.context.onSetTitle(title);
    return (

{title}

...

    );
  }

}

export default ContactPage;
<|endoftext|>


<commit_before>/**
 * @Author: Wahaj Shamim <wahaj>
 * @Date:   2018-01-24T09:50:36+11:00
 * @Email:  inbox.wahaj@gmail.com
 * @Last modified by:   wahaj
 * @Last modified time: 2018-04-20T11:48:20+10:00
 *
 * dbKoda - a modern, open source code editor, for MongoDB.
 * Copyright (C) 2017-2018 Southbank Software
 *
 * This file is part of dbKoda.
 *
 * dbKoda is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * dbKoda is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with dbKoda.  If not, see <http://www.gnu.org/licenses/>.
 */

import _ from 'lodash';
import { observable, toJS, runInAction, action, set } from 'mobx';
import Ajv from 'ajv';

export const FieldBindings = {
  text: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur'],
  password: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur'],
  number: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onValueChange', 'onBlur'],
  checkbox: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onClick', 'onBlur'],
  file: ['name', 'value', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur'],
  select: ['name', 'value', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur']
};

export class JsonForm {
  api: null;
  formSchema: null;
  validationSchema: null;
  formErrors: [];
  validateErrors: null;
  @observable isFormInvalid: false;

  constructor(api) {
    this.api = api;
    this.formErrors = [];

    this.getSubForms = this.getSubForms.bind(this);
  }
  /**
   * Function to load schema to create form fields
   */
  loadFormSchema(jsonSchema) {
    this.formSchema = observable(jsonSchema);

    // This loop will add the additional required properties which are required by renderer UI fields
    for (const subform in this.formSchema) {
      if (this.formSchema.hasOwnProperty(subform)) {
        this.formSchema[subform].fields.forEach(field => {
          this.addAdditionalFieldProps(field, this.formSchema[subform]);
        });
      }
    }
  }
  /**
   * Function to load validation schema to validate form fields
   */
  loadValidationSchema(jsonSchema) {
    this.validationSchema = jsonSchema;
  }
  /**
   * Function to get the subform keys to get subform fields
   */
  getSubForms() {
    return Object.keys(this.formSchema);
  }
  /**
   * Function to get subform fields
   */
  getSubformFields(selectedSubform, column) {
    const fieldsCol = [];
    const subForm = this.formSchema[selectedSubform];
    if (subForm.fields) {
      subForm.fields.forEach(field => {
        if (field.column === column) {
          fieldsCol.push(field);
        }
      });
    }
    return fieldsCol;
  }
  /**
   * Function to get the subform Tips if there are any
   */
  getSubformTips(selectedSubform) {
    const subForm = this.formSchema[selectedSubform];
    if (subForm && subForm.tips) {
      return subForm.tips;
    }
    return [];
  }
  /**
   * Private function to add additional Props to a form field which are used in UI renderer of fields
   */
  @action
  addAdditionalFieldProps(field, subForm) {
    field.id = field.name; // fix to add id as required by UI fields
    field.subForm = subForm;
    field.$ = (siblingFieldName, siblingSubform = '') => {
      // get Sibling field of the sub form
      let refField = null;
      if (siblingSubform !== '') {
        refField = _.find(this.formSchema[siblingSubform].fields, f => {
          return f.name === siblingFieldName;
        });
      } else {
        refField = _.find(field.subForm.fields, f => {
          return f.name === siblingFieldName;
        });
      }
      return refField;
    };
    set(field, { error: '' });
    field.onChange = action(e => {
      this.updateFieldValue(field, e.currentTarget.value);
    });
    field.onBlur = () => {
      this.validateForm();
    };
    if (field.type == 'checkbox') {
      field.onClick = action(e => {
        this.updateFieldValue(field, e.currentTarget.checked);
      });
    } else if (field.type === 'number') {
      field.onValueChange = action(value => {
        this.updateFieldValue(field, value);
      });
    }
    field.bind = () => {
      const binds = FieldBindings[field.type];
      const objProp = {};
      for (const prop of binds) {
        if (field.hasOwnProperty(prop)) {
          objProp[prop] = field[prop];
        }
      }
      return objProp;
    };
  }
  /**
   * Function to update field value and also update values of referenced fields if defined in the schema
   */
  @action
  updateFieldValue(field, newValue) {
    field.value = newValue;
    if (field.refFields) {
      this.updateReferencedFields(field);
    }
    this.validateForm();
  }

  /**
   * Function to update referenced fields values defined in the schema
   */
  @action
  updateReferencedFields(field) {
    const { subForm } = field;
    if (subForm.fields) {
      for (const fld of field.refFields) {
        const refField = _.find(subForm.fields, f => {
          return f.name === fld;
        });
        if (field.type === 'checkbox') {
          if (refField.checkbox === 'enabled') {
            refField.disabled = !field.value;
          } else if (refField.checkbox === 'disabled') {
            refField.disabled = field.value;
          }
        }
      }
    }
  }
  /**
   * Function to validate form fields if Validation schema is present
   */
  validateForm() {
    if (!this.validationSchema) {
      throw new Error('Validation Json schema is not set for the form.');
    }
    if (!this.validateErrors) {
      const ajv = new Ajv({
        removeAdditional: true,
        $data: true,
        allErrors: true,
        jsonPointers: true
      });
      require('ajv-keywords')(ajv);
      require('ajv-errors')(ajv);
      this.validateErrors = ajv.compile(this.validationSchema);
    }
    // reset the errors if present from previous validation
    if (this.formErrors) {
      for (const error of this.formErrors) {
        const errorPath = error.dataPath.substring(1, error.dataPath.lastIndexOf('.'));
        let field = _.at(this.formSchema, errorPath);
        if ((field.length > 0 && field[0] === undefined) || field[0] === null) {
          const schemaPath = error.schemaPath
            .substring(1, error.schemaPath.lastIndexOf('/'))
            .replace(/\/properties\//g, '.')
            .replace(/(\/items\/)(\d*)/, '[$2]')
            .substr(1, error.schemaPath.length);
          field = _.at(this.formSchema, schemaPath);
        }
        if (field.length > 0 && field[0]) {
          runInAction(() => {
            field[0].error = '';
          });
        }
      }
      this.formErrors = [];
    }

    const formData = toJS(this.formSchema);
    const status = this.validateErrors(formData);
    const { errors } = this.validateErrors;

    // if Errors found, Add them to fields for UI display and keep their record in form
    if (errors) {
      for (const error of errors) {
        const errorPath = error.dataPath.substring(1, error.dataPath.lastIndexOf('.'));
        let field = _.at(this.formSchema, errorPath);
        if ((field.length > 0 && field[0] === undefined) || field[0] === null) {
          const schemaPath = error.schemaPath
            .substring(1, error.schemaPath.lastIndexOf('/'))
            .replace(/\/properties\//g, '.')
            .replace(/(\/items\/)(\d*)/, '[$2]')
            .substr(1, error.schemaPath.length);
          field = _.at(this.formSchema, schemaPath);
        }
        if (field.length > 0 && field[0]) {
          runInAction(() => {
            field[0].error = error.message;
          });
        }
      }
      this.formErrors = errors;
    }
    runInAction(() => {
      this.isFormInvalid = !(this.formErrors && this.formErrors.length <= 0);
    });
    return { status, formData };
  }
}
<commit_msg>Minor exception fix<commit_after>/**
 * @Author: Wahaj Shamim <wahaj>
 * @Date:   2018-01-24T09:50:36+11:00
 * @Email:  inbox.wahaj@gmail.com
 * @Last modified by:   wahaj
 * @Last modified time: 2018-05-18T12:17:59+10:00
 *
 * dbKoda - a modern, open source code editor, for MongoDB.
 * Copyright (C) 2017-2018 Southbank Software
 *
 * This file is part of dbKoda.
 *
 * dbKoda is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * dbKoda is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with dbKoda.  If not, see <http://www.gnu.org/licenses/>.
 */

import _ from 'lodash';
import { observable, toJS, runInAction, action, set } from 'mobx';
import Ajv from 'ajv';

export const FieldBindings = {
  text: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur'],
  password: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur'],
  number: ['name', 'value', 'type', 'id', 'placeholder', 'disabled', 'onValueChange', 'onBlur'],
  checkbox: [
    'name',
    'value',
    'type',
    'id',
    'placeholder',
    'disabled',
    'onClick',
    'onChange',
    'onBlur'
  ],
  file: ['name', 'value', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur'],
  select: ['name', 'value', 'id', 'placeholder', 'disabled', 'onChange', 'onBlur']
};

export class JsonForm {
  api: null;
  formSchema: null;
  validationSchema: null;
  formErrors: [];
  validateErrors: null;
  @observable isFormInvalid: false;

  constructor(api) {
    this.api = api;
    this.formErrors = [];

    this.getSubForms = this.getSubForms.bind(this);
  }
  /**
   * Function to load schema to create form fields
   */
  loadFormSchema(jsonSchema) {
    this.formSchema = observable(jsonSchema);

    // This loop will add the additional required properties which are required by renderer UI fields
    for (const subform in this.formSchema) {
      if (this.formSchema.hasOwnProperty(subform)) {
        this.formSchema[subform].fields.forEach(field => {
          this.addAdditionalFieldProps(field, this.formSchema[subform]);
        });
      }
    }
  }
  /**
   * Function to load validation schema to validate form fields
   */
  loadValidationSchema(jsonSchema) {
    this.validationSchema = jsonSchema;
  }
  /**
   * Function to get the subform keys to get subform fields
   */
  getSubForms() {
    return Object.keys(this.formSchema);
  }
  /**
   * Function to get subform fields
   */
  getSubformFields(selectedSubform, column) {
    const fieldsCol = [];
    const subForm = this.formSchema[selectedSubform];
    if (subForm.fields) {
      subForm.fields.forEach(field => {
        if (field.column === column) {
          fieldsCol.push(field);
        }
      });
    }
    return fieldsCol;
  }
  /**
   * Function to get the subform Tips if there are any
   */
  getSubformTips(selectedSubform) {
    const subForm = this.formSchema[selectedSubform];
    if (subForm && subForm.tips) {
      return subForm.tips;
    }
    return [];
  }
  /**
   * Private function to add additional Props to a form field which are used in UI renderer of fields
   */
  @action
  addAdditionalFieldProps(field, subForm) {
    field.id = field.name; // fix to add id as required by UI fields
    field.subForm = subForm;
    field.$ = (siblingFieldName, siblingSubform = '') => {
      // get Sibling field of the sub form
      let refField = null;
      if (siblingSubform !== '') {
        refField = _.find(this.formSchema[siblingSubform].fields, f => {
          return f.name === siblingFieldName;
        });
      } else {
        refField = _.find(field.subForm.fields, f => {
          return f.name === siblingFieldName;
        });
      }
      return refField;
    };
    set(field, { error: '' });
    field.onChange = action(e => {
      if (e.currentTarget.type === 'checkbox') {
        return;
      }
      this.updateFieldValue(field, e.currentTarget.value);
    });
    field.onBlur = () => {
      this.validateForm();
    };
    if (field.type == 'checkbox') {
      field.onClick = action(e => {
        this.updateFieldValue(field, e.currentTarget.checked);
      });
    } else if (field.type === 'number') {
      field.onValueChange = action(value => {
        this.updateFieldValue(field, value);
      });
    }
    field.bind = () => {
      const binds = FieldBindings[field.type];
      const objProp = {};
      for (const prop of binds) {
        if (field.hasOwnProperty(prop)) {
          objProp[prop] = field[prop];
        }
      }
      return objProp;
    };
  }
  /**
   * Function to update field value and also update values of referenced fields if defined in the schema
   */
  @action
  updateFieldValue(field, newValue) {
    field.value = newValue;
    if (field.refFields) {
      this.updateReferencedFields(field);
    }
    this.validateForm();
  }

  /**
   * Function to update referenced fields values defined in the schema
   */
  @action
  updateReferencedFields(field) {
    const { subForm } = field;
    if (subForm.fields) {
      for (const fld of field.refFields) {
        const refField = _.find(subForm.fields, f => {
          return f.name === fld;
        });
        if (field.type === 'checkbox') {
          if (refField.checkbox === 'enabled') {
            refField.disabled = !field.value;
          } else if (refField.checkbox === 'disabled') {
            refField.disabled = field.value;
          }
        }
      }
    }
  }
  /**
   * Function to validate form fields if Validation schema is present
   */
  validateForm() {
    if (!this.validationSchema) {
      throw new Error('Validation Json schema is not set for the form.');
    }
    if (!this.validateErrors) {
      const ajv = new Ajv({
        removeAdditional: true,
        $data: true,
        allErrors: true,
        jsonPointers: true
      });
      require('ajv-keywords')(ajv);
      require('ajv-errors')(ajv);
      this.validateErrors = ajv.compile(this.validationSchema);
    }
    // reset the errors if present from previous validation
    if (this.formErrors) {
      for (const error of this.formErrors) {
        const errorPath = error.dataPath.substring(1, error.dataPath.lastIndexOf('.'));
        let field = _.at(this.formSchema, errorPath);
        if ((field.length > 0 && field[0] === undefined) || field[0] === null) {
          const schemaPath = error.schemaPath
            .substring(1, error.schemaPath.lastIndexOf('/'))
            .replace(/\/properties\//g, '.')
            .replace(/(\/items\/)(\d*)/, '[$2]')
            .substr(1, error.schemaPath.length);
          field = _.at(this.formSchema, schemaPath);
        }
        if (field.length > 0 && field[0]) {
          runInAction(() => {
            field[0].error = '';
          });
        }
      }
      this.formErrors = [];
    }

    const formData = toJS(this.formSchema);
    const status = this.validateErrors(formData);
    const { errors } = this.validateErrors;

    // if Errors found, Add them to fields for UI display and keep their record in form
    if (errors) {
      for (const error of errors) {
        const errorPath = error.dataPath.substring(1, error.dataPath.lastIndexOf('.'));
        let field = _.at(this.formSchema, errorPath);
        if ((field.length > 0 && field[0] === undefined) || field[0] === null) {
          const schemaPath = error.schemaPath
            .substring(1, error.schemaPath.lastIndexOf('/'))
            .replace(/\/properties\//g, '.')
            .replace(/(\/items\/)(\d*)/, '[$2]')
            .substr(1, error.schemaPath.length);
          field = _.at(this.formSchema, schemaPath);
        }
        if (field.length > 0 && field[0]) {
          runInAction(() => {
            field[0].error = error.message;
          });
        }
      }
      this.formErrors = errors;
    }
    runInAction(() => {
      this.isFormInvalid = !(this.formErrors && this.formErrors.length <= 0);
    });
    return { status, formData };
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import { storiesOf } from '@storybook/react';
import {
  text, boolean, select, button
} from '@storybook/addon-knobs';
import { State, Store } from '@sambego/storybook-state';
import { action } from '@storybook/addon-actions';
import OptionsHelper from '../../utils/helpers/options-helper';
import { notes, info } from './documentation';
import Confirm from './confirm.component.js';

const store = new Store({
  open: false
});
const handleCancel = () => {
  action('cancel')();
  store.set({ open: false });
};
const handleOpen = () => {
  action('open')();
  store.set({ open: true });
};
const handleConfirm = () => {
  action('confirm')();
  store.set({ open: false });
};

storiesOf('Confirm', module)
  .addParameters({
    info: {
      propTablesExclude: [State]
    }
  })
  .add('default', () => {
    button('open', handleOpen);
    const children = text('children', 'This is an example of a confirm.');
    const title = text('title', 'Are you sure?');
    const enableBackgroundUI = boolean('enableBackgroundUI', false);
    const disableEscKey = boolean('disableEscKey', false);
    const ariaRole = text('ariaRole', Confirm.defaultProps.ariaRole);
    const height = text('height', '');
    const subtitle = text('subtitle', '');
    const size = select('size', OptionsHelper.sizesFull, Confirm.defaultProps.size);
    const showCloseIcon = boolean('showCloseIcon', Confirm.defaultProps.showCloseIcon);
    const autoFocus = boolean('autoFocus', Confirm.defaultProps.autoFocus);
    const stickyFormFooter = boolean('stickyFormFooter', false);
    const confirmLabel = text('confirmLabel', '');
    const cancelLabel = text('cancelLabel', '');

    return (
      <State store={ store }>
        <Confirm
          title={ title }
          open={ store.get('open') }
          enableBackgroundUI={ enableBackgroundUI }
          disableEscKey={ disableEscKey }
          ariaRole={ ariaRole }
          height={ height }
          subtitle={ subtitle }
          size={ size }
          showCloseIcon={ showCloseIcon }
          autoFocus={ autoFocus }
          stickyFormFooter={ stickyFormFooter }
          confirmLabel={ confirmLabel }
          cancelLabel={ cancelLabel }
          onConfirm={ handleConfirm }
          onCancel={ handleCancel }
        >
          {children}
        </Confirm>
      </State>
    );
  },
  {
    info: { text: info },
    notes: { markdown: notes }
  });
<commit_msg>add preview button to confirm story<commit_after>import React from 'react';
import { storiesOf } from '@storybook/react';
import {
  text, boolean, select, button
} from '@storybook/addon-knobs';
import { State, Store } from '@sambego/storybook-state';
import { action } from '@storybook/addon-actions';
import OptionsHelper from '../../utils/helpers/options-helper';
import { notes, info } from './documentation';
import Button from '../button';
import Confirm from './confirm.component.js';

const store = new Store({
  open: false
});
const handleCancel = () => {
  action('cancel')();
  store.set({ open: false });
};
const handleOpen = () => {
  action('open')();
  store.set({ open: true });
};
const handleConfirm = () => {
  action('confirm')();
  store.set({ open: false });
};

storiesOf('Confirm', module)
  .addParameters({
    info: {
      propTablesExclude: [State, Button]
    }
  })
  .add(
    'default',
    () => {
      const children = text('children', 'This is an example of a confirm.');
      const title = text('title', 'Are you sure?');
      const enableBackgroundUI = boolean('enableBackgroundUI', false);
      const disableEscKey = boolean('disableEscKey', false);
      const ariaRole = text('ariaRole', Confirm.defaultProps.ariaRole);
      const height = text('height', '');
      const subtitle = text('subtitle', '');
      const size = select('size', OptionsHelper.sizesFull, Confirm.defaultProps.size);
      const showCloseIcon = boolean('showCloseIcon', Confirm.defaultProps.showCloseIcon);
      const autoFocus = boolean('autoFocus', Confirm.defaultProps.autoFocus);
      const stickyFormFooter = boolean('stickyFormFooter', false);
      const confirmLabel = text('confirmLabel', '');
      const cancelLabel = text('cancelLabel', '');

      return (
        <State store={ store }>
          <Button onClick={ handleOpen }>Open Preview</Button>
          <Confirm
            title={ title }
            open={ store.get('open') }
            enableBackgroundUI={ enableBackgroundUI }
            disableEscKey={ disableEscKey }
            ariaRole={ ariaRole }
            height={ height }
            subtitle={ subtitle }
            size={ size }
            showCloseIcon={ showCloseIcon }
            autoFocus={ autoFocus }
            stickyFormFooter={ stickyFormFooter }
            confirmLabel={ confirmLabel }
            cancelLabel={ cancelLabel }
            onConfirm={ handleConfirm }
            onCancel={ handleCancel }
          >
            {children}
          </Confirm>
        </State>
      );
    },
    {
      info: { text: info },
      notes: { markdown: notes }
    }
  );
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import styles from './styles.scss';

class SpecialForm extends Component {
  state = {  }
  render() {
    console.log(this.props.title)
    return (

        <form name="coupon" action="../../pages/received/" data-netlify="true">

              Your Name:
              <input type="text" name="name"/>

              Your Email:
              <input type="email" name="email"/>

              <input type="text" name="coupon" value={this.props.title}/>

            <button className="couponBtn a" type="submit">Send</button>
            <button className="couponBtn b" type="button" onClick={this.props.onClick}>Cancel</button>

        </form>

    );
  }
}

export default SpecialForm;
<commit_msg>Changed value to defaultValue in special form<commit_after>import React, {Component} from 'react';
import PropTypes from 'prop-types';

import styles from './styles.scss';

class SpecialForm extends Component {
  render() {
    return (

        <form name="coupon" action="../../pages/received/" data-netlify="true">

              Your Name:
              <input type="text" name="name"/>

              Your Email:
              <input type="email" name="email"/>

              <input type="text" name="coupon" defaultValue={this.props.title}/>

            <button className="couponBtn a" type="submit">Send</button>
            <button className="couponBtn b" type="button" onClick={this.props.onClick}>Cancel</button>

        </form>

    );
  }
}

SpecialForm.propTypes = {
  title: PropTypes.string,
  onClick: PropTypes.func,
}

export default SpecialForm;
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Link } from 'react-router';
import { Glyphicon } from 'react-bootstrap';
import MedicineCard from '../../components/Common/MedicineCard';
import './ComparePage.css';
import api from '../../api/api';

class ComparePage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      primaryMedicineId: '12345',
      substitutes: [],
    };
  }

  componentWillMount() {
    api.getTopSellerMedicines().then((medicines) => {
      medicines.topSeller.forEach((seller) => {
        if(seller[Object.keys(seller)[0]]._medicineId == this.props.params.primaryMedicineId) {
          this.setState({substitutes: seller[Object.keys(seller)[0]]._substitute});
        }
      })
    })
  }
  render() {
    const { substitutes } = this.state;
    return (

            <Link className="homeButton" to="/">
              <Glyphicon glyph="home" />
            </Link>
            <Link className="cartButton" to="/cart">
              <Glyphicon glyph="shopping-cart" />
            </Link>
            Substitutes for XYZ

          {substitutes.map((subs, key) => <MedicineCard medName={subs} isSubsBanner={true} key={key}/>)}

    );
  }
}

export default ComparePage;
<commit_msg>added header<commit_after>import React, { Component } from 'react';
import { Link } from 'react-router';
import { Glyphicon } from 'react-bootstrap';
import MedicineCard from '../../components/Common/MedicineCard';
import './ComparePage.css';
import api from '../../api/api';

class ComparePage extends Component {
  constructor(props) {
    super(props);

    this.state = {
      primaryMedicineId: '12345',
      substitutes: [],
      medicineName: ''
    };
  }

  componentWillMount() {
    api.getTopSellerMedicines().then((medicines) => {
      medicines.topSeller.forEach((seller) => {
        if(seller[Object.keys(seller)[0]]._medicineId == this.props.params.primaryMedicineId) {
          console.log('seller[Object.keys(seller)[0]]')
          this.setState({substitutes: seller[Object.keys(seller)[0]]._substitute, medicineName: seller[Object.keys(seller)[0]]._medicineName});
        }
      })
    })
  }
  render() {
    const { substitutes, medicineName } = this.state;
    return (

            <Link className="homeButton" to="/">
              <Glyphicon glyph="home" />
            </Link>
            <Link className="cartButton" to="/cart">
              <Glyphicon glyph="shopping-cart" />
            </Link>
            Substitutes for {medicineName}

          {substitutes.map((subs, key) => <MedicineCard medName={subs} isSubsBanner={true} key={key}/>)}

    );
  }
}

export default ComparePage;
<|endoftext|>


<commit_before>import React, { PropTypes } from 'react';
import { Button } from 'react-bootstrap';
import { Table, Column, Cell } from 'fixed-data-table';
import PropertyTextCell from './PropertyTextCell';
import userProfileImg from '../../images/user-profile-icon.png';
import styles from './styles.module.css';

const TABLE_WIDTH = 1000;
const ROW_HEIGHT = 50;
const TABLE_OFFSET = 2;
const PROPERTY_COLUMN_WIDTH = 200;
const COLUMN_WIDTH = (TABLE_WIDTH - PROPERTY_COLUMN_WIDTH);
const HEADERS = ['PROPERTY', 'DATA'];

export default class UserRow extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      numRows: 1,
      propertyIds: []
    }
  }

  componentDidMount() {
    const propertyIds = this.getPropertyIds();
    this.setState({propertyIds});

    const numRows = propertyIds.length;
    this.setState({numRows});
  }

  renderTable = () => {
    if (!this.props.userPage) return null;
    const tableHeight = ((this.state.numRows + 1) * ROW_HEIGHT) + TABLE_OFFSET;
    return (

        {this.renderPropertyColumn()}
        {this.renderDataColumn()}

    );
  }

  renderPropertyColumn() {
    const header = HEADERS[0];
    const propertyTitles = this.getPropertyTitles();

    return (
      <Column
        key={0}
        header={header}
        cell={
          <PropertyTextCell data={propertyTitles} />
        }
        width={PROPERTY_COLUMN_WIDTH}
      />
    )
  }

  renderDataColumn() {
    const header = HEADERS[1];
    const cellData = this.getCellData();

    return (
      <Column
          key={1}
          header={<Cell>{header}</Cell>}
          cell={
            <PropertyTextCell data={cellData} />
          }
          width={COLUMN_WIDTH} />
    );
  }

  getPropertyIds() {
    const { row, propertyTypes, firstName, lastName, dob } = this.props;

    const propertyIds = Object.keys(row).filter((id) => {
      if (dob && id === dob.id) return false;
      return (id !== firstName.id && id !== lastName.id);
    });

    return propertyIds;
  }

  getPropertyTitles() {
    const { propertyTypes } = this.props;
    var propertyIds = this.state.propertyIds;
    var headers = propertyIds.map((id) => {
      var property = propertyTypes.filter((propertyType) => {
        return propertyType.id === id;
      });
      return property[0].title;
    });

    return headers;
  }

  getCellData(){
    const { row, propertyTypes, firstName, lastName, dob } = this.props;
    const propertyIds = this.state.propertyIds;

    return propertyIds.map((id) => {
      var formatValue = this.props.formatValueFn([row][0][id]);
      return formatValue;
    });
  }

  selectUser = () => {
    if (this.props.userPage) return;
    this.props.selectUserFn(this.props.row);
  }

  renderBackButton = () => {
    if (!this.props.userPage) return null;
    return (

        <Button onClick={this.props.backFn} bsStyle="primary" className={styles.backButton}>Back to results</Button>

    );
  }

  getFirstNameVal = () => {
    return this.props.formatValueFn(this.props.row[this.props.firstName.id]);
  }

  getLastNameVal = () => {
    return this.props.formatValueFn(this.props.row[this.props.lastName.id]);
  }

  renderDOB = () => {
    if (!this.props.dob) return null;
    const dobVal = this.props.row[this.props.dob.id];
    if (!dobVal) return null;
    return
Date of Birth: {this.props.formatValueFn(dobVal)}
;
  }

  getClassName = () => {
    return (this.props.userPage) ? styles.userProfile : styles.userListItem;
  }

  renderUserProfile = () => {
    return (

First Name: {this.getFirstNameVal()}

Last Name: {this.getLastNameVal()}

          {this.renderDOB()}

    );
  }

  getContainerClassName = () => {
    return (this.props.userPage) ? '' : styles.userListContainer;
  }

  render() {
    return (

        {this.renderBackButton()}
        {this.renderUserProfile()}
        {this.renderTable()}

    );
  }

  static propTypes = {
    row: PropTypes.object.isRequired,
    propertyTypes: PropTypes.array.isRequired,
    firstName: PropTypes.object.isRequired,
    lastName: PropTypes.object.isRequired,
    dob: PropTypes.object,
    selectUserFn: PropTypes.func,
    backFn: PropTypes.func,
    userPage: PropTypes.bool,
    formatValueFn: PropTypes.func
  }
}
<commit_msg>Save rowKeys to state, implement promises to manage asynchronous behavior<commit_after>import React, { PropTypes } from 'react';
import { Button } from 'react-bootstrap';
import { Table, Column, Cell } from 'fixed-data-table';
import PropertyTextCell from './PropertyTextCell';
import userProfileImg from '../../images/user-profile-icon.png';
import styles from './styles.module.css';

const TABLE_WIDTH = 1000;
const ROW_HEIGHT = 50;
const TABLE_OFFSET = 2;
const PROPERTY_COLUMN_WIDTH = 200;
const COLUMN_WIDTH = (TABLE_WIDTH - PROPERTY_COLUMN_WIDTH);
const HEADERS = ['PROPERTY', 'DATA'];

export default class UserRow extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      rowKeys: [],
      propertyIds: [],
      numRows: 1
    }
  }

  componentDidMount() {
    this.setObjectKeys()
      .then((res) => {
        return this.setPropertyIds(res);
      })
      .then((res) => {
        this.setNumRows(res);
      })
  }

  setObjectKeys() {
    const { row } = this.props;
    const rowKeys = Object.keys(row);

    return new Promise((resolve, reject) => {
      this.setState({rowKeys}, () => {resolve(this.state.rowKeys)});
    });
  }

  setPropertyIds(keys) {
    const { propertyTypes, firstName, lastName, dob } = this.props;

    const propertyIds = keys.filter((id) => {
      if (dob && id === dob.id) return false;
      return (id !== firstName.id && id !== lastName.id);
    });

    return new Promise((resolve, reject) => {
      this.setState({propertyIds}, () => {
        resolve(this.state.propertyIds);
      });
    });
  }

  setNumRows(propertyIds) {
    this.setState({numRows: propertyIds.length});
  }

  renderTable = () => {
    if (!this.props.userPage) return null;
    const tableHeight = ((this.state.numRows + 1) * ROW_HEIGHT) + TABLE_OFFSET;
    return (

        {this.renderPropertyColumn()}
        {this.renderDataColumn()}

    );
  }

  renderPropertyColumn() {
    const header = HEADERS[0];
    const propertyTitles = this.getPropertyTitles();

    return (
      <Column
        key={0}
        header={header}
        cell={
          <PropertyTextCell data={propertyTitles} />
        }
        width={PROPERTY_COLUMN_WIDTH}
      />
    )
  }

  renderDataColumn() {
    const header = HEADERS[1];
    const cellData = this.getCellData();

    return (
      <Column
          key={1}
          header={<Cell>{header}</Cell>}
          cell={
            <PropertyTextCell data={cellData} />
          }
          width={COLUMN_WIDTH} />
    );
  }

  getPropertyTitles() {
    const { propertyTypes } = this.props;
    const { propertyIds } = this.state;

    var headers = propertyIds.map((id) => {
      var property = propertyTypes.filter((propertyType) => {
        return propertyType.id === id;
      });
      return property[0].title;
    });

    return headers;
  }

  getCellData(){
    const { row, propertyTypes, firstName, lastName, dob } = this.props;
    const { propertyIds } = this.state;

    return propertyIds.map((id) => {
      var formatValue = this.props.formatValueFn([row][0][id]);
      return formatValue;
    });
  }

  selectUser = () => {
    if (this.props.userPage) return;
    this.props.selectUserFn(this.props.row);
  }

  renderBackButton = () => {
    if (!this.props.userPage) return null;
    return (

        <Button onClick={this.props.backFn} bsStyle="primary" className={styles.backButton}>Back to results</Button>

    );
  }

  getFirstNameVal = () => {
    return this.props.formatValueFn(this.props.row[this.props.firstName.id]);
  }

  getLastNameVal = () => {
    return this.props.formatValueFn(this.props.row[this.props.lastName.id]);
  }

  renderDOB = () => {
    if (!this.props.dob) return null;
    const dobVal = this.props.row[this.props.dob.id];
    if (!dobVal) return null;
    return
Date of Birth: {this.props.formatValueFn(dobVal)}
;
  }

  getClassName = () => {
    return (this.props.userPage) ? styles.userProfile : styles.userListItem;
  }

  renderUserProfile = () => {
    return (

First Name: {this.getFirstNameVal()}

Last Name: {this.getLastNameVal()}

          {this.renderDOB()}

    );
  }

  getContainerClassName = () => {
    return (this.props.userPage) ? '' : styles.userListContainer;
  }

  render() {
    return (

        {this.renderBackButton()}
        {this.renderUserProfile()}
        {this.renderTable()}

    );
  }

  static propTypes = {
    row: PropTypes.object.isRequired,
    propertyTypes: PropTypes.array.isRequired,
    firstName: PropTypes.object.isRequired,
    lastName: PropTypes.object.isRequired,
    dob: PropTypes.object,
    selectUserFn: PropTypes.func,
    backFn: PropTypes.func,
    userPage: PropTypes.bool,
    formatValueFn: PropTypes.func
  }
}
<|endoftext|>


<commit_before>import React from 'react';
import LogoSVG from "../../../components/logo";
import {Link} from "react-router-dom";

const LogoItem = () => {
  const alphaStyles = {
    opacity: .4,
    color: "grey",
    position: "absolute",
  };
  console.log("foo")

  return (

      <Link to="/" className="logo-wrapper">
        <LogoSVG dotsColor="#00a99c"/>

Hearth

Lounge

        ALPHA
      </Link>

  )
};

export default LogoItem;
<commit_msg>test commit<commit_after>import React from 'react';
import LogoSVG from "../../../components/logo";
import {Link} from "react-router-dom";

const LogoItem = () => {
  const alphaStyles = {
    opacity: .4,
    color: "grey",
    position: "absolute",
  };
  console.log("foo");

  return (

      <Link to="/" className="logo-wrapper">
        <LogoSVG dotsColor="#00a99c"/>

Hearth

Lounge

        ALPHA
      </Link>

  )
};

export default LogoItem;
<|endoftext|>


<commit_before>var SystemRenderer = require('../SystemRenderer'),
    MaskManager = require('./managers/MaskManager'),
    StencilManager = require('./managers/StencilManager'),
    FilterManager = require('./managers/FilterManager'),
    BlendModeManager = require('./managers/BlendModeManager'),
    RenderTarget = require('./utils/RenderTarget'),
    ObjectRenderer = require('./utils/ObjectRenderer'),
    TextureManager = require('./TextureManager'),
    RenderTextureManager = require('./RenderTextureManager'),
    WebGLState = require('./WebGLState'),
    createContext = require('pixi-gl-core').createContext,
    mapWebGLBlendModesToPixi = require('./utils/mapWebGLBlendModesToPixi'),
    mapWebGLDrawModesToPixi = require('./utils/mapWebGLDrawModesToPixi'),
    utils = require('../../utils'),
    CONST = require('../../const');

/**
 * The WebGLRenderer draws the scene and all its content onto a webGL enabled canvas. This renderer
 * should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs.
 * So no need for Sprite Batches or Sprite Clouds.
 * Don't forget to add the view to your DOM or you will not see anything :)
 *
 * @class
 * @memberof PIXI
 * @extends PIXI.SystemRenderer
 * @param [width=0] {number} the width of the canvas view
 * @param [height=0] {number} the height of the canvas view
 * @param [options] {object} The optional renderer parameters
 * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
 * @param [options.transparent=false] {boolean} If the render view is transparent, default false
 * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false
 * @param [options.antialias=false] {boolean} sets antialias. If not available natively then FXAA antialiasing is used
 * @param [options.forceFXAA=false] {boolean} forces FXAA antialiasing to be used over native. FXAA is faster, but may not always look as great
 * @param [options.resolution=1] {number} the resolution of the renderer retina would be 2
 * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or
 *      not before the new render pass. If you wish to set this to false, you *must* set preserveDrawingBuffer to `true`.
 * @param [options.preserveDrawingBuffer=false] {boolean} enables drawing buffer preservation, enable this if
 *      you need to call toDataUrl on the webgl context.
 * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
 */
function WebGLRenderer(width, height, options)
{
    options = options || {};

    SystemRenderer.call(this, 'WebGL', width, height, options);

    /**
     * The type of this renderer as a standardised const
     *
     * @member {number}//
     *
     */
    this.type = CONST.RENDERER_TYPE.WEBGL;

    this.handleContextLost = this.handleContextLost.bind(this);
    this.handleContextRestored = this.handleContextRestored.bind(this);

    this.view.addEventListener('webglcontextlost', this.handleContextLost, false);
    this.view.addEventListener('webglcontextrestored', this.handleContextRestored, false);

    /**
     * The options passed in to create a new webgl context.
     *
     * @member {object}
     * @private
     */
    this._contextOptions = {
        alpha: this.transparent,
        antialias: options.antialias,
        premultipliedAlpha: this.transparent && this.transparent !== 'notMultiplied',
        stencil: true,
        preserveDrawingBuffer: options.preserveDrawingBuffer
    };

    this._backgroundColorRgba[3] = this.transparent ? 0 : 1;

    /**
     * Manages the masks using the stencil buffer.
     *
     * @member {PIXI.MaskManager}
     */
    this.maskManager = new MaskManager(this);

    /**
     * Manages the stencil buffer.
     *
     * @member {PIXI.StencilManager}
     */
    this.stencilManager = new StencilManager(this);

    /**
     * Manages the filters.
     *
     * @member {PIXI.FilterManager}
     */
    this.filterManager = new FilterManager(this);
    this.blendModeManager = new BlendModeManager(this);

    /**
     * The currently active ObjectRenderer.
     *
     * @member {PIXI.ObjectRenderer}
     */
    this.currentRenderer = new ObjectRenderer(this);

    this.initPlugins();

    // initialize the context so it is ready for the managers.
    this.gl = createContext(this.view, this._contextOptions);

    this.state = new WebGLState(this.gl);

    this._initContext();

    // map some webGL blend and drawmodes..
    this.blendModes = mapWebGLBlendModesToPixi(gl);
    this.drawModes = mapWebGLDrawModesToPixi(gl)

    //alert(this.state )
    this._activeShader = null;

    /**
     * Holds the current render target
     *
     * @member {PIXI.RenderTarget}
     */
    this._activeRenderTarget = null;
    this._activeTextureLocation = null;
    this._activeTexture = null;
}

// constructor
WebGLRenderer.prototype = Object.create(SystemRenderer.prototype);
WebGLRenderer.prototype.constructor = WebGLRenderer;
module.exports = WebGLRenderer;
utils.pluginTarget.mixin(WebGLRenderer);

/**
 * Creates the WebGL context
 *
 * @private
 */
WebGLRenderer.prototype._initContext = function ()
{
    var gl = this.gl;

    // create a texture manager...
    this.textureManager = new TextureManager(gl);
    this.renderTextureManager = new RenderTextureManager(gl);

    this.state.resetToDefault();

    this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true);
    this.rootRenderTarget.clearColor = this._backgroundColorRgba;

    this.bindRenderTarget(this.rootRenderTarget);

    this.emit('context', gl);

    // setup the width/height properties and gl viewport
    this.resize(this.width, this.height);
};

/**
 * Renders the object to its webGL view
 *
 * @param object {PIXI.DisplayObject} the object to be rendered
 */
WebGLRenderer.prototype.render = function (displayObject, renderTexture, clear, doNotUpdateTransform)
{
    this.emit('prerender');

    // no point rendering if our context has been blown up!
    if (this.gl.isContextLost())
    {
        return;
    }

    this._lastObjectRendered = displayObject;

    if(!doNotUpdateTransform)
    {
        var cacheParent = displayObject.parent;
        displayObject.parent = this._tempDisplayObjectParent;
        // update the scene graph
        displayObject.updateTransform();
        displayObject.parent = cacheParent;
    }

    //TODO - do we need renderDisplayObject?
    var renderTarget = this.rootRenderTarget;
    var clear = this.clearBeforeRender;

    // MOVE OUT?
    if(renderTexture)
    {
        var baseTexture = renderTexture.baseTexture;

        if(!baseTexture._glRenderTargets[gl.id])
        {
            this.renderTextureManager.updateTexture(baseTexture);
        }

        renderTarget =  baseTexture._glRenderTargets[gl.id];

        // TODO make this optional..
        clear = true;
    }

    this.bindRenderTarget(renderTarget);

    if(clear)
    {
        renderTarget.clear();
    }

    displayObject.renderWebGL(this);

    this.currentRenderer.flush();

    this.emit('postrender');
};

/**
 * Changes the current renderer to the one given in parameter
 *
 * @param objectRenderer {PIXI.ObjectRenderer} The object renderer to use.
 */
WebGLRenderer.prototype.setObjectRenderer = function (objectRenderer)
{
    if (this.currentRenderer === objectRenderer)
    {
        return;
    }

    this.currentRenderer.stop();
    this.currentRenderer = objectRenderer;
    this.currentRenderer.start();
};

/**
 * Resizes the webGL view to the specified width and height.
 *
 * @param width {number} the new width of the webGL view
 * @param height {number} the new height of the webGL view
 */
WebGLRenderer.prototype.resize = function (width, height)
{
    SystemRenderer.prototype.resize.call(this, width, height);

    this.filterManager.resize(width, height);
    this.rootRenderTarget.resize(width, height);

    if(this._activeRenderTarget === this.rootRenderTarget)
    {
        this.rootRenderTarget.activate();

        if(this._activeShader)
        {
            this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true);
        }
    }
};

WebGLRenderer.prototype.setBlendMode = function (mode)
{
    // fill in here..
}

WebGLRenderer.prototype.bindRenderTexture = function (renderTexture)
{
    this.bindRenderTarget( renderTexture.baseTexture.textureBuffer, renderTexture.frame );
}

/**
 * Changes the current render target to the one given in parameter
 *
 * @param renderTarget {PIXI.RenderTarget} the new render target
 */
WebGLRenderer.prototype.bindRenderTarget = function (renderTarget, frame)
{
    if(renderTarget !== this._activeRenderTarget)
    {
        this._activeRenderTarget = renderTarget;

        if(this._activeShader)
        {
            this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true);
        }

        renderTarget.activate(frame);

        this.stencilManager.setMaskStack( renderTarget.stencilMaskStack );
    }
}

WebGLRenderer.prototype.bindShader = function (shader)
{
    //TODO cache
    if(this._activeShader !== shader)
    {
        this._activeShader = shader;
        shader.bind();

        // automatically set the projection matrix
        shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true);
    }
}

WebGLRenderer.prototype.bindTexture = function (texture, location)
{
    var gl = this.gl;

    //TODO test perf of cache?
    location = location || 0;

    if(this._activeTextureLocation !== location)//
    {
        this._activeTextureLocation = location
        gl.activeTexture(gl.TEXTURE0 + location );
    }

    //TODO - can we cache this texture too?
    this._activeTexture = texture;

    if (!texture._glTextures[gl.id])
    {
        // this will also bind the texture..
        this.textureManager.updateTexture(texture);
    }
    else
    {
        // bind the current texture
        texture._glTextures[gl.id].bind();
    }
}

/**
 * resets WebGL state so you can render things however you fancy!
 * @return {[type]} [description]
 */
WebGLRenderer.prototype.reset = function ()
{
    this._activeShader = null;
    this._activeRenderTarget = null;

    // bind the main frame buffer (the screen);
    this.rootRenderTarget.activate();

    this.state.reset();
}

/**
 * Handles a lost webgl context
 *
 * @private
 */
WebGLRenderer.prototype.handleContextLost = function (event)
{
    event.preventDefault();
};

/**
 * Handles a restored webgl context
 *
 * @private
 */
WebGLRenderer.prototype.handleContextRestored = function ()
{
    this._initContext();
    this.textureManager.removeAll();
};

/**
 * Removes everything from the renderer (event listeners, spritebatch, etc...)
 *
 * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.
 */
WebGLRenderer.prototype.destroy = function (removeView)
{
    this.destroyPlugins();

    // remove listeners
    this.view.removeEventListener('webglcontextlost', this.handleContextLost);
    this.view.removeEventListener('webglcontextrestored', this.handleContextRestored);

    this.textureManager.destroyAll();

    // call base destroy
    SystemRenderer.prototype.destroy.call(this, removeView);

    this.uid = 0;

    // destroy the managers
    this.maskManager.destroy();
    this.stencilManager.destroy();
    this.filterManager.destroy();

    this.maskManager = null;
    this.filterManager = null;
    this.currentRenderer = null;

    this.handleContextLost = null;
    this.handleContextRestored = null;

    this._contextOptions = null;

    this.gl.useProgram(null);
    this.gl = null;
};

<commit_msg>fixed clear<commit_after>var SystemRenderer = require('../SystemRenderer'),
    MaskManager = require('./managers/MaskManager'),
    StencilManager = require('./managers/StencilManager'),
    FilterManager = require('./managers/FilterManager'),
    BlendModeManager = require('./managers/BlendModeManager'),
    RenderTarget = require('./utils/RenderTarget'),
    ObjectRenderer = require('./utils/ObjectRenderer'),
    TextureManager = require('./TextureManager'),
    RenderTextureManager = require('./RenderTextureManager'),
    WebGLState = require('./WebGLState'),
    createContext = require('pixi-gl-core').createContext,
    mapWebGLBlendModesToPixi = require('./utils/mapWebGLBlendModesToPixi'),
    mapWebGLDrawModesToPixi = require('./utils/mapWebGLDrawModesToPixi'),
    utils = require('../../utils'),
    CONST = require('../../const');

/**
 * The WebGLRenderer draws the scene and all its content onto a webGL enabled canvas. This renderer
 * should be used for browsers that support webGL. This Render works by automatically managing webGLBatchs.
 * So no need for Sprite Batches or Sprite Clouds.
 * Don't forget to add the view to your DOM or you will not see anything :)
 *
 * @class
 * @memberof PIXI
 * @extends PIXI.SystemRenderer
 * @param [width=0] {number} the width of the canvas view
 * @param [height=0] {number} the height of the canvas view
 * @param [options] {object} The optional renderer parameters
 * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional
 * @param [options.transparent=false] {boolean} If the render view is transparent, default false
 * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false
 * @param [options.antialias=false] {boolean} sets antialias. If not available natively then FXAA antialiasing is used
 * @param [options.forceFXAA=false] {boolean} forces FXAA antialiasing to be used over native. FXAA is faster, but may not always look as great
 * @param [options.resolution=1] {number} the resolution of the renderer retina would be 2
 * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or
 *      not before the new render pass. If you wish to set this to false, you *must* set preserveDrawingBuffer to `true`.
 * @param [options.preserveDrawingBuffer=false] {boolean} enables drawing buffer preservation, enable this if
 *      you need to call toDataUrl on the webgl context.
 * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation.
 */
function WebGLRenderer(width, height, options)
{
    options = options || {};

    SystemRenderer.call(this, 'WebGL', width, height, options);

    /**
     * The type of this renderer as a standardised const
     *
     * @member {number}//
     *
     */
    this.type = CONST.RENDERER_TYPE.WEBGL;

    this.handleContextLost = this.handleContextLost.bind(this);
    this.handleContextRestored = this.handleContextRestored.bind(this);

    this.view.addEventListener('webglcontextlost', this.handleContextLost, false);
    this.view.addEventListener('webglcontextrestored', this.handleContextRestored, false);

    /**
     * The options passed in to create a new webgl context.
     *
     * @member {object}
     * @private
     */
    this._contextOptions = {
        alpha: this.transparent,
        antialias: options.antialias,
        premultipliedAlpha: this.transparent && this.transparent !== 'notMultiplied',
        stencil: true,
        preserveDrawingBuffer: options.preserveDrawingBuffer
    };

    this._backgroundColorRgba[3] = this.transparent ? 0 : 1;

    /**
     * Manages the masks using the stencil buffer.
     *
     * @member {PIXI.MaskManager}
     */
    this.maskManager = new MaskManager(this);

    /**
     * Manages the stencil buffer.
     *
     * @member {PIXI.StencilManager}
     */
    this.stencilManager = new StencilManager(this);

    /**
     * Manages the filters.
     *
     * @member {PIXI.FilterManager}
     */
    this.filterManager = new FilterManager(this);
    this.blendModeManager = new BlendModeManager(this);

    /**
     * The currently active ObjectRenderer.
     *
     * @member {PIXI.ObjectRenderer}
     */
    this.currentRenderer = new ObjectRenderer(this);

    this.initPlugins();

    // initialize the context so it is ready for the managers.
    this.gl = createContext(this.view, this._contextOptions);

    this.state = new WebGLState(this.gl);

    this._initContext();

    // map some webGL blend and drawmodes..
    this.blendModes = mapWebGLBlendModesToPixi(gl);
    this.drawModes = mapWebGLDrawModesToPixi(gl)

    //alert(this.state )
    this._activeShader = null;

    /**
     * Holds the current render target
     *
     * @member {PIXI.RenderTarget}
     */
    this._activeRenderTarget = null;
    this._activeTextureLocation = null;
    this._activeTexture = null;
}

// constructor
WebGLRenderer.prototype = Object.create(SystemRenderer.prototype);
WebGLRenderer.prototype.constructor = WebGLRenderer;
module.exports = WebGLRenderer;
utils.pluginTarget.mixin(WebGLRenderer);

/**
 * Creates the WebGL context
 *
 * @private
 */
WebGLRenderer.prototype._initContext = function ()
{
    var gl = this.gl;

    // create a texture manager...
    this.textureManager = new TextureManager(gl);
    this.renderTextureManager = new RenderTextureManager(gl);

    this.state.resetToDefault();

    this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true);
    this.rootRenderTarget.clearColor = this._backgroundColorRgba;

    this.bindRenderTarget(this.rootRenderTarget);

    this.emit('context', gl);

    // setup the width/height properties and gl viewport
    this.resize(this.width, this.height);
};

/**
 * Renders the object to its webGL view
 *
 * @param object {PIXI.DisplayObject} the object to be rendered
 */
WebGLRenderer.prototype.render = function (displayObject, renderTexture, clear, doNotUpdateTransform)
{
    this.emit('prerender');

    // no point rendering if our context has been blown up!
    if (this.gl.isContextLost())
    {
        return;
    }

    this._lastObjectRendered = displayObject;

    if(!doNotUpdateTransform)
    {
        // update the scene graph
        var cacheParent = displayObject.parent;
        displayObject.parent = this._tempDisplayObjectParent;
        displayObject.updateTransform();
        displayObject.parent = cacheParent;
    }

    //TODO - do we need renderDisplayObject?
    var renderTarget = this.rootRenderTarget;
    var clear = clear || this.clearBeforeRender;

    // MOVE OUT?
    if(renderTexture)
    {
        var baseTexture = renderTexture.baseTexture;

        if(!baseTexture._glRenderTargets[gl.id])
        {
            this.renderTextureManager.updateTexture(baseTexture);
        }

        renderTarget =  baseTexture._glRenderTargets[gl.id];
    }

    this.bindRenderTarget(renderTarget);

    if(clear)
    {
        renderTarget.clear();
    }

    displayObject.renderWebGL(this);

    this.currentRenderer.flush();

    this.emit('postrender');
};

/**
 * Changes the current renderer to the one given in parameter
 *
 * @param objectRenderer {PIXI.ObjectRenderer} The object renderer to use.
 */
WebGLRenderer.prototype.setObjectRenderer = function (objectRenderer)
{
    if (this.currentRenderer === objectRenderer)
    {
        return;
    }

    this.currentRenderer.stop();
    this.currentRenderer = objectRenderer;
    this.currentRenderer.start();
};

/**
 * Resizes the webGL view to the specified width and height.
 *
 * @param width {number} the new width of the webGL view
 * @param height {number} the new height of the webGL view
 */
WebGLRenderer.prototype.resize = function (width, height)
{
    SystemRenderer.prototype.resize.call(this, width, height);

    this.filterManager.resize(width, height);
    this.rootRenderTarget.resize(width, height);

    if(this._activeRenderTarget === this.rootRenderTarget)
    {
        this.rootRenderTarget.activate();

        if(this._activeShader)
        {
            this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true);
        }
    }
};

WebGLRenderer.prototype.setBlendMode = function (mode)
{
    // fill in here..
}

WebGLRenderer.prototype.bindRenderTexture = function (renderTexture)
{
    this.bindRenderTarget( renderTexture.baseTexture.textureBuffer, renderTexture.frame );
}

/**
 * Changes the current render target to the one given in parameter
 *
 * @param renderTarget {PIXI.RenderTarget} the new render target
 */
WebGLRenderer.prototype.bindRenderTarget = function (renderTarget, frame)
{
    if(renderTarget !== this._activeRenderTarget)
    {
        this._activeRenderTarget = renderTarget;

        if(this._activeShader)
        {
            this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true);
        }

        renderTarget.activate(frame);

        this.stencilManager.setMaskStack( renderTarget.stencilMaskStack );
    }
}

WebGLRenderer.prototype.bindShader = function (shader)
{
    //TODO cache
    if(this._activeShader !== shader)
    {
        this._activeShader = shader;
        shader.bind();

        // automatically set the projection matrix
        shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true);
    }
}

WebGLRenderer.prototype.bindTexture = function (texture, location)
{
    var gl = this.gl;

    //TODO test perf of cache?
    location = location || 0;

    if(this._activeTextureLocation !== location)//
    {
        this._activeTextureLocation = location
        gl.activeTexture(gl.TEXTURE0 + location );
    }

    //TODO - can we cache this texture too?
    this._activeTexture = texture;

    if (!texture._glTextures[gl.id])
    {
        // this will also bind the texture..
        this.textureManager.updateTexture(texture);
    }
    else
    {
        // bind the current texture
        texture._glTextures[gl.id].bind();
    }
}

/**
 * resets WebGL state so you can render things however you fancy!
 * @return {[type]} [description]
 */
WebGLRenderer.prototype.reset = function ()
{
    this._activeShader = null;
    this._activeRenderTarget = null;

    // bind the main frame buffer (the screen);
    this.rootRenderTarget.activate();

    this.state.reset();
}

/**
 * Handles a lost webgl context
 *
 * @private
 */
WebGLRenderer.prototype.handleContextLost = function (event)
{
    event.preventDefault();
};

/**
 * Handles a restored webgl context
 *
 * @private
 */
WebGLRenderer.prototype.handleContextRestored = function ()
{
    this._initContext();
    this.textureManager.removeAll();
};

/**
 * Removes everything from the renderer (event listeners, spritebatch, etc...)
 *
 * @param [removeView=false] {boolean} Removes the Canvas element from the DOM.
 */
WebGLRenderer.prototype.destroy = function (removeView)
{
    this.destroyPlugins();

    // remove listeners
    this.view.removeEventListener('webglcontextlost', this.handleContextLost);
    this.view.removeEventListener('webglcontextrestored', this.handleContextRestored);

    this.textureManager.destroyAll();

    // call base destroy
    SystemRenderer.prototype.destroy.call(this, removeView);

    this.uid = 0;

    // destroy the managers
    this.maskManager.destroy();
    this.stencilManager.destroy();
    this.filterManager.destroy();

    this.maskManager = null;
    this.filterManager = null;
    this.currentRenderer = null;

    this.handleContextLost = null;
    this.handleContextRestored = null;

    this._contextOptions = null;

    this.gl.useProgram(null);
    this.gl = null;
};

<|endoftext|>


<commit_before>define(['marionette', 'collections/users'], function(Marionette, Users) {

    var UserItem = Marionette.ItemView.extend({
        tagName: 'li',
        template: _.template("<%=FULLNAME%> - <% if (LAST) { %><%=VISITS%> Visits (Last Visit: <%=LAST%>)<% } else { %>*NEW*<% } %> [<%=REMOTE=='1' ? 'Remote' : 'On-site'%>]"),
        className: function() {
            return this.model.get('VISITS') == 0 ? 'new' : ''
        },
    })

    var LoadingView = Marionette.ItemView.extend({
        tagName: 'li',
        template: _.template('')
    })

    return Marionette.CollectionView.extend({
        //template: _.template('
Users

'),
        //childViewContainer: '.users',
        tagName: 'ul',
        childView: UserItem,
        emptyView: LoadingView,
        className: 'visit_users',

        initialize: function(options) {
            this.collection = new Users()
            this.collection.queryParams.visit = options.visit
            this.collection.fetch()
        }
    })

})<commit_msg>add empty in addition to loading view<commit_after>define(['marionette', 'collections/users'], function(Marionette, Users) {

    var UserItem = Marionette.ItemView.extend({
        tagName: 'li',
        template: _.template("<%=FULLNAME%> - <% if (LAST) { %><%=VISITS%> Visits (Last Visit: <%=LAST%>)<% } else { %>*NEW*<% } %> [<%=REMOTE=='1' ? 'Remote' : 'On-site'%>]"),
        className: function() {
            return this.model.get('VISITS') == 0 ? 'new' : ''
        },
    })

    var LoadingView = Marionette.ItemView.extend({
        tagName: 'li',
        template: _.template('')
    })

    var EmptyView = Marionette.ItemView.extend({
        tagName: 'li',
        template: _.template('No users regsitered yet')
    })

    return Marionette.CollectionView.extend({
        //template: _.template('
Users

'),
        //childViewContainer: '.users',
        tagName: 'ul',
        childView: UserItem,
        emptyView: LoadingView,
        className: 'visit_users',

        getEmptyView: function(e) {
            if (this.collection.fetched) return EmptyView
            else return LoadingView
        },

        initialize: function(options) {
            this.collection = new Users()
            this.collection.queryParams.visit = options.visit
            var self = this
            this.collection.fetch().done(function() {
                self.collection.fetched = true
                self.collection.trigger('reset')
            })
        }
    })

})<|endoftext|>