<commit_before>/*
 *
 * (c) Copyright Ascensio System SIA 2010-2019
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
 * street, Riga, Latvia, EU, LV-1050.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
*/
/**
 *    CellEditor.js
 *
 *    CellEditor Controller
 *
 *    Created by Maxim Kadushkin on 08 April 2014
 *    Copyright (c) 2018 Ascensio System SIA. All rights reserved.
 *
 */

define([
    'core',
    'spreadsheeteditor/main/app/view/CellEditor',
    'spreadsheeteditor/main/app/view/NameManagerDlg'
], function (Viewport) {
    'use strict';

    SSE.Controllers.CellEditor = Backbone.Controller.extend({
        views: [
            'CellEditor'
        ],

        events: function() {
            return {
                'keyup input#ce-cell-name': _.bind(this.onCellName,this),
                'keyup textarea#ce-cell-content': _.bind(this.onKeyupCellEditor,this),
                'blur textarea#ce-cell-content': _.bind(this.onBlurCellEditor,this),
                'click button#ce-btn-expand': _.bind(this.expandEditorField,this),
                'click button#ce-func-label': _.bind(this.onInsertFunction, this)
            };
        },

        initialize: function() {
            this.addListeners({
                'CellEditor': {},
                'Viewport': {
                    'layout:resizedrag': _.bind(this.onLayoutResize, this)
                },
                'Common.Views.Header': {
                    'formulabar:hide': function (state) {
                        this.editor.setVisible(!state);
                        Common.localStorage.setBool('sse-hidden-formula', state);
                        Common.NotificationCenter.trigger('layout:changed', 'celleditor', state?'hidden':'showed');
                    }.bind(this)
                }
            });
        },

        setApi: function(api) {
            this.api = api;

            this.api.isCEditorFocused = false;
            this.api.asc_registerCallback('asc_onSelectionNameChanged', _.bind(this.onApiCellSelection, this));
            this.api.asc_registerCallback('asc_onEditCell', _.bind(this.onApiEditCell, this));
            this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(this.onApiDisconnect,this));
            Common.NotificationCenter.on('api:disconnect', _.bind(this.onApiDisconnect, this));
            Common.NotificationCenter.on('cells:range', _.bind(this.onCellsRange, this));
            this.api.asc_registerCallback('asc_onLockDefNameManager', _.bind(this.onLockDefNameManager, this));
            this.api.asc_registerCallback('asc_onInputKeyDown', _.bind(this.onInputKeyDown, this));

            return this;
        },

        setMode: function(mode) {
            this.mode = mode;

            this.editor.$btnfunc[this.mode.isEdit?'removeClass':'addClass']('disabled');
            this.editor.btnNamedRanges.setVisible(this.mode.isEdit && !this.mode.isEditDiagram && !this.mode.isEditMailMerge);

            if ( this.mode.isEdit ) {
                this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onApiSelectionChanged, this));
            }
        },

        onInputKeyDown: function(e) {
            if (Common.UI.Keys.UP === e.keyCode || Common.UI.Keys.DOWN === e.keyCode ||
                Common.UI.Keys.TAB === e.keyCode || Common.UI.Keys.RETURN === e.keyCode || Common.UI.Keys.ESC === e.keyCode ||
                Common.UI.Keys.LEFT === e.keyCode || Common.UI.Keys.RIGHT === e.keyCode) {
                var menu = $('#menu-formula-selection'); // for formula menu
                if (menu.hasClass('open'))
                    menu.find('.dropdown-menu').trigger('keydown', e);
            }
        },

        onLaunch: function() {
            this.editor = this.getView('CellEditor');
            this.bindViewEvents(this.editor, this.events);

            this.editor.$el.parent().find('.after').css({zIndex: '4'}); // for spreadsheets - bug 23127
            this.editor.btnNamedRanges.menu.on('item:click', _.bind(this.onNamedRangesMenu, this))
                                           .on('show:before', _.bind(this.onNameBeforeShow, this));
            this.namedrange_locked = false;
        },

        onApiEditCell: function(state) {
            if (state == Asc.c_oAscCellEditorState.editStart){
                this.api.isCellEdited = true;
                this.editor.cellNameDisabled(true);
            } else if (state == Asc.c_oAscCellEditorState.editInCell) {
                this.api.isCEditorFocused = 'clear';
            } else if (state == Asc.c_oAscCellEditorState.editEnd) {
                this.api.isCellEdited = false;
                this.api.isCEditorFocused = false;
                this.editor.cellNameDisabled(false);
            }
            this.editor.$btnfunc.toggleClass('disabled', state == Asc.c_oAscCellEditorState.editText);
        },

        onApiCellSelection: function(info) {
            this.editor.updateCellInfo(info);
        },

        onApiSelectionChanged: function(info) {
            var seltype = info.asc_getFlags().asc_getSelectionType(),
                coauth_disable = (!this.mode.isEditMailMerge && !this.mode.isEditDiagram) ? (info.asc_getLocked() === true || info.asc_getLockedTable() === true) : false;

            var is_chart_text   = seltype == Asc.c_oAscSelectionType.RangeChartText,
                is_chart        = seltype == Asc.c_oAscSelectionType.RangeChart,
                is_shape_text   = seltype == Asc.c_oAscSelectionType.RangeShapeText,
                is_shape        = seltype == Asc.c_oAscSelectionType.RangeShape,
                is_image        = seltype == Asc.c_oAscSelectionType.RangeImage,
                is_mode_2       = is_shape_text || is_shape || is_chart_text || is_chart;

            this.editor.$btnfunc.toggleClass('disabled', is_image || is_mode_2 || coauth_disable);
        },

        onApiDisconnect: function() {
            this.mode.isEdit = false;

            var controller = this.getApplication().getController('FormulaDialog');
            if (controller) {
                controller.hideDialog();
            }

            if (!this.mode.isEdit) {
                $('#ce-func-label', this.editor.el).addClass('disabled');
                this.editor.btnNamedRanges.setVisible(false);
            }
        },

        onCellsRange: function(status) {
            this.editor.cellNameDisabled(status != Asc.c_oAscSelectionDialogType.None);
            this.editor.$btnfunc.toggleClass('disabled', status != Asc.c_oAscSelectionDialogType.None);
        },

        onLayoutResize: function(o, r) {
            if (r == 'cell:edit') {
                if (this.editor.$el.height() > 19) {
                    if (!this.editor.$btnexpand.hasClass('btn-collapse'))
                        this.editor.$btnexpand['addClass']('btn-collapse');
                } else {
                    this.editor.$btnexpand['removeClass']('btn-collapse');
                }
            }
        },

        onCellName: function(e) {
            if (e.keyCode == Common.UI.Keys.RETURN){
                var name = this.editor.$cellname.val();
                if (name && name.length) {
                    this.api.asc_findCell(name);
                }

                Common.NotificationCenter.trigger('edit:complete', this.editor);
            }
        },

        onBlurCellEditor: function() {
            if (this.api.isCEditorFocused == 'clear')
                this.api.isCEditorFocused = undefined;
            else if (this.api.isCellEdited)
                this.api.isCEditorFocused = true;
//            if (Common.Utils.isIE && !$('#menu-formula-selection').hasClass('open')) {// for formula menu
//                this.getApplication().getController('DocumentHolder').documentHolder.focus();
//            }
        },

        onKeyupCellEditor: function(e) {
            if(e.keyCode == Common.UI.Keys.RETURN && !e.altKey){
                this.api.isCEditorFocused = 'clear';
            }
        },

        expandEditorField: function() {
            if (this.editor.$el.height() > 19) {
                this.editor.keep_height = this.editor.$el.height();
                this.editor.$el.height(19);
                this.editor.$btnexpand['removeClass']('btn-collapse');
            } else {
                this.editor.$el.height(this.editor.keep_height||74);
                this.editor.$btnexpand['addClass']('btn-collapse');
            }

            Common.NotificationCenter.trigger('layout:changed', 'celleditor');
            Common.NotificationCenter.trigger('edit:complete', this.editor, {restorefocus:true});
        },

        onInsertFunction: function() {
            if ( this.mode.isEdit && !this.editor.$btnfunc['hasClass']('disabled')) {
                var controller = this.getApplication().getController('FormulaDialog');
                if (controller) {
                    $('#ce-func-label', this.editor.el).blur();
                    controller.showDialog();
                }
            }
        },

        onNamedRangesMenu: function(menu, item) {
            var me = this;
            if (item.options.value=='manager') {
                var wc = this.api.asc_getWorksheetsCount(),
                        i = -1,
                        items = [], sheetNames = [];
                while (++i < wc) {
                    if (!this.api.asc_isWorksheetHidden(i)) {
                        sheetNames[i] = this.api.asc_getWorksheetName(i);
                        items.push({displayValue: sheetNames[i], value: i});
                    }
                }

                (new SSE.Views.NameManagerDlg({
                    api: this.api,
                    handler: function(result) {
                        Common.NotificationCenter.trigger('edit:complete', this.editor);
                    },
                    locked: this.namedrange_locked,
                    sheets: items,
                    sheetNames: sheetNames,
                    ranges: this.api.asc_getDefinedNames(Asc.c_oAscGetDefinedNamesList.All),
                    props : this.api.asc_getDefaultDefinedName(),
                    sort  : this.rangeListSort
                })).on('close', function(win){
                    me.rangeListSort = win.getSettings();
                }).show();
            } else {
                this.api.asc_findCell(item.caption);
                Common.NotificationCenter.trigger('edit:complete', this.editor);
            }
        },

        onNameBeforeShow: function() {
            var names = this.api.asc_getDefinedNames(Asc.c_oAscGetDefinedNamesList.WorksheetWorkbook),
                rangesMenu = this.editor.btnNamedRanges.menu,
                prev_name='';

            rangesMenu.removeItems(2, rangesMenu.items.length-1);
            names.sort(function(item1, item2) {
                var n1 = item1.asc_getName(true).toLowerCase(),
                    n2 = item2.asc_getName(true).toLowerCase();
                if (n1==n2) return 0;
                return (n1<n2) ? -1 : 1;
            });
            _.each(names, function(field, index) {
                var name = field.asc_getName(true);
                if (prev_name !== name) {
                    rangesMenu.addItem(new Common.UI.MenuItem({
                        caption : name
                    }));
                }
                prev_name = name;
            });
            this.editor.btnNamedRanges.menu.items[1].setVisible(rangesMenu.items.length>2);
        },

        onLockDefNameManager: function(state) {
            this.namedrange_locked = (state == Asc.c_oAscDefinedNameReason.LockDefNameManager);
        }
    });
});<commit_msg>[SSE] Save height of the formula bar in the browser local storage<commit_after>/*
 *
 * (c) Copyright Ascensio System SIA 2010-2019
 *
 * This program is a free software product. You can redistribute it and/or
 * modify it under the terms of the GNU Affero General Public License (AGPL)
 * version 3 as published by the Free Software Foundation. In accordance with
 * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
 * that Ascensio System SIA expressly excludes the warranty of non-infringement
 * of any third-party rights.
 *
 * This program is distributed WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR  PURPOSE. For
 * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
 *
 * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
 * street, Riga, Latvia, EU, LV-1050.
 *
 * The  interactive user interfaces in modified source and object code versions
 * of the Program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU AGPL version 3.
 *
 * Pursuant to Section 7(b) of the License you must retain the original Product
 * logo when distributing the program. Pursuant to Section 7(e) we decline to
 * grant you any rights under trademark law for use of our trademarks.
 *
 * All the Product's GUI elements, including illustrations and icon sets, as
 * well as technical writing content are licensed under the terms of the
 * Creative Commons Attribution-ShareAlike 4.0 International. See the License
 * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
 *
*/
/**
 *    CellEditor.js
 *
 *    CellEditor Controller
 *
 *    Created by Maxim Kadushkin on 08 April 2014
 *    Copyright (c) 2018 Ascensio System SIA. All rights reserved.
 *
 */

define([
    'core',
    'spreadsheeteditor/main/app/view/CellEditor',
    'spreadsheeteditor/main/app/view/NameManagerDlg'
], function (Viewport) {
    'use strict';

    SSE.Controllers.CellEditor = Backbone.Controller.extend({
        views: [
            'CellEditor'
        ],

        events: function() {
            return {
                'keyup input#ce-cell-name': _.bind(this.onCellName,this),
                'keyup textarea#ce-cell-content': _.bind(this.onKeyupCellEditor,this),
                'blur textarea#ce-cell-content': _.bind(this.onBlurCellEditor,this),
                'click button#ce-btn-expand': _.bind(this.expandEditorField,this),
                'click button#ce-func-label': _.bind(this.onInsertFunction, this)
            };
        },

        initialize: function() {
            this.addListeners({
                'CellEditor': {},
                'Viewport': {
                    'layout:resizedrag': _.bind(this.onLayoutResize, this)
                },
                'Common.Views.Header': {
                    'formulabar:hide': function (state) {
                        this.editor.setVisible(!state);
                        Common.localStorage.setBool('sse-hidden-formula', state);
                        Common.NotificationCenter.trigger('layout:changed', 'celleditor', state?'hidden':'showed');
                    }.bind(this)
                }
            });
        },

        setApi: function(api) {
            this.api = api;

            this.api.isCEditorFocused = false;
            this.api.asc_registerCallback('asc_onSelectionNameChanged', _.bind(this.onApiCellSelection, this));
            this.api.asc_registerCallback('asc_onEditCell', _.bind(this.onApiEditCell, this));
            this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', _.bind(this.onApiDisconnect,this));
            Common.NotificationCenter.on('api:disconnect', _.bind(this.onApiDisconnect, this));
            Common.NotificationCenter.on('cells:range', _.bind(this.onCellsRange, this));
            this.api.asc_registerCallback('asc_onLockDefNameManager', _.bind(this.onLockDefNameManager, this));
            this.api.asc_registerCallback('asc_onInputKeyDown', _.bind(this.onInputKeyDown, this));

            return this;
        },

        setMode: function(mode) {
            this.mode = mode;

            this.editor.$btnfunc[this.mode.isEdit?'removeClass':'addClass']('disabled');
            this.editor.btnNamedRanges.setVisible(this.mode.isEdit && !this.mode.isEditDiagram && !this.mode.isEditMailMerge);

            if ( this.mode.isEdit ) {
                this.api.asc_registerCallback('asc_onSelectionChanged', _.bind(this.onApiSelectionChanged, this));
            }
        },

        onInputKeyDown: function(e) {
            if (Common.UI.Keys.UP === e.keyCode || Common.UI.Keys.DOWN === e.keyCode ||
                Common.UI.Keys.TAB === e.keyCode || Common.UI.Keys.RETURN === e.keyCode || Common.UI.Keys.ESC === e.keyCode ||
                Common.UI.Keys.LEFT === e.keyCode || Common.UI.Keys.RIGHT === e.keyCode) {
                var menu = $('#menu-formula-selection'); // for formula menu
                if (menu.hasClass('open'))
                    menu.find('.dropdown-menu').trigger('keydown', e);
            }
        },

        onLaunch: function() {
            this.editor = this.getView('CellEditor');
            this.bindViewEvents(this.editor, this.events);

            this.editor.$el.parent().find('.after').css({zIndex: '4'}); // for spreadsheets - bug 23127

            var val = Common.localStorage.getItem('sse-celleditor-height');
            this.editor.keep_height = (val!==null && parseInt(val)>0) ? parseInt(val) : 74;
            if (Common.localStorage.getBool('sse-celleditor-expand')) {
                this.editor.$el.height(this.editor.keep_height);
                this.onLayoutResize(undefined, 'cell:edit');
            }

            this.editor.btnNamedRanges.menu.on('item:click', _.bind(this.onNamedRangesMenu, this))
                                           .on('show:before', _.bind(this.onNameBeforeShow, this));
            this.namedrange_locked = false;
        },

        onApiEditCell: function(state) {
            if (state == Asc.c_oAscCellEditorState.editStart){
                this.api.isCellEdited = true;
                this.editor.cellNameDisabled(true);
            } else if (state == Asc.c_oAscCellEditorState.editInCell) {
                this.api.isCEditorFocused = 'clear';
            } else if (state == Asc.c_oAscCellEditorState.editEnd) {
                this.api.isCellEdited = false;
                this.api.isCEditorFocused = false;
                this.editor.cellNameDisabled(false);
            }
            this.editor.$btnfunc.toggleClass('disabled', state == Asc.c_oAscCellEditorState.editText);
        },

        onApiCellSelection: function(info) {
            this.editor.updateCellInfo(info);
        },

        onApiSelectionChanged: function(info) {
            var seltype = info.asc_getFlags().asc_getSelectionType(),
                coauth_disable = (!this.mode.isEditMailMerge && !this.mode.isEditDiagram) ? (info.asc_getLocked() === true || info.asc_getLockedTable() === true) : false;

            var is_chart_text   = seltype == Asc.c_oAscSelectionType.RangeChartText,
                is_chart        = seltype == Asc.c_oAscSelectionType.RangeChart,
                is_shape_text   = seltype == Asc.c_oAscSelectionType.RangeShapeText,
                is_shape        = seltype == Asc.c_oAscSelectionType.RangeShape,
                is_image        = seltype == Asc.c_oAscSelectionType.RangeImage,
                is_mode_2       = is_shape_text || is_shape || is_chart_text || is_chart;

            this.editor.$btnfunc.toggleClass('disabled', is_image || is_mode_2 || coauth_disable);
        },

        onApiDisconnect: function() {
            this.mode.isEdit = false;

            var controller = this.getApplication().getController('FormulaDialog');
            if (controller) {
                controller.hideDialog();
            }

            if (!this.mode.isEdit) {
                $('#ce-func-label', this.editor.el).addClass('disabled');
                this.editor.btnNamedRanges.setVisible(false);
            }
        },

        onCellsRange: function(status) {
            this.editor.cellNameDisabled(status != Asc.c_oAscSelectionDialogType.None);
            this.editor.$btnfunc.toggleClass('disabled', status != Asc.c_oAscSelectionDialogType.None);
        },

        onLayoutResize: function(o, r) {
            if (r == 'cell:edit') {
                if (this.editor.$el.height() > 19) {
                    if (!this.editor.$btnexpand.hasClass('btn-collapse'))
                        this.editor.$btnexpand['addClass']('btn-collapse');
                    o && Common.localStorage.setItem('sse-celleditor-height', this.editor.$el.height());
                    o && Common.localStorage.setBool('sse-celleditor-expand', true);
                } else {
                    this.editor.$btnexpand['removeClass']('btn-collapse');
                    o && Common.localStorage.setBool('sse-celleditor-expand', false);
                }
            }
        },

        onCellName: function(e) {
            if (e.keyCode == Common.UI.Keys.RETURN){
                var name = this.editor.$cellname.val();
                if (name && name.length) {
                    this.api.asc_findCell(name);
                }

                Common.NotificationCenter.trigger('edit:complete', this.editor);
            }
        },

        onBlurCellEditor: function() {
            if (this.api.isCEditorFocused == 'clear')
                this.api.isCEditorFocused = undefined;
            else if (this.api.isCellEdited)
                this.api.isCEditorFocused = true;
//            if (Common.Utils.isIE && !$('#menu-formula-selection').hasClass('open')) {// for formula menu
//                this.getApplication().getController('DocumentHolder').documentHolder.focus();
//            }
        },

        onKeyupCellEditor: function(e) {
            if(e.keyCode == Common.UI.Keys.RETURN && !e.altKey){
                this.api.isCEditorFocused = 'clear';
            }
        },

        expandEditorField: function() {
            if (this.editor.$el.height() > 19) {
                this.editor.keep_height = this.editor.$el.height();
                this.editor.$el.height(19);
                this.editor.$btnexpand['removeClass']('btn-collapse');
                Common.localStorage.setBool('sse-celleditor-expand', false);
            } else {
                this.editor.$el.height(this.editor.keep_height);
                this.editor.$btnexpand['addClass']('btn-collapse');
                Common.localStorage.setBool('sse-celleditor-expand', true);
            }

            Common.NotificationCenter.trigger('layout:changed', 'celleditor');
            Common.NotificationCenter.trigger('edit:complete', this.editor, {restorefocus:true});
        },

        onInsertFunction: function() {
            if ( this.mode.isEdit && !this.editor.$btnfunc['hasClass']('disabled')) {
                var controller = this.getApplication().getController('FormulaDialog');
                if (controller) {
                    $('#ce-func-label', this.editor.el).blur();
                    controller.showDialog();
                }
            }
        },

        onNamedRangesMenu: function(menu, item) {
            var me = this;
            if (item.options.value=='manager') {
                var wc = this.api.asc_getWorksheetsCount(),
                        i = -1,
                        items = [], sheetNames = [];
                while (++i < wc) {
                    if (!this.api.asc_isWorksheetHidden(i)) {
                        sheetNames[i] = this.api.asc_getWorksheetName(i);
                        items.push({displayValue: sheetNames[i], value: i});
                    }
                }

                (new SSE.Views.NameManagerDlg({
                    api: this.api,
                    handler: function(result) {
                        Common.NotificationCenter.trigger('edit:complete', this.editor);
                    },
                    locked: this.namedrange_locked,
                    sheets: items,
                    sheetNames: sheetNames,
                    ranges: this.api.asc_getDefinedNames(Asc.c_oAscGetDefinedNamesList.All),
                    props : this.api.asc_getDefaultDefinedName(),
                    sort  : this.rangeListSort
                })).on('close', function(win){
                    me.rangeListSort = win.getSettings();
                }).show();
            } else {
                this.api.asc_findCell(item.caption);
                Common.NotificationCenter.trigger('edit:complete', this.editor);
            }
        },

        onNameBeforeShow: function() {
            var names = this.api.asc_getDefinedNames(Asc.c_oAscGetDefinedNamesList.WorksheetWorkbook),
                rangesMenu = this.editor.btnNamedRanges.menu,
                prev_name='';

            rangesMenu.removeItems(2, rangesMenu.items.length-1);
            names.sort(function(item1, item2) {
                var n1 = item1.asc_getName(true).toLowerCase(),
                    n2 = item2.asc_getName(true).toLowerCase();
                if (n1==n2) return 0;
                return (n1<n2) ? -1 : 1;
            });
            _.each(names, function(field, index) {
                var name = field.asc_getName(true);
                if (prev_name !== name) {
                    rangesMenu.addItem(new Common.UI.MenuItem({
                        caption : name
                    }));
                }
                prev_name = name;
            });
            this.editor.btnNamedRanges.menu.items[1].setVisible(rangesMenu.items.length>2);
        },

        onLockDefNameManager: function(state) {
            this.namedrange_locked = (state == Asc.c_oAscDefinedNameReason.LockDefNameManager);
        }
    });
});<|endoftext|>


<commit_before>import React, { PropTypes, Component } from 'react';
import {
	View,
	ListView,
	RefreshControl
} from 'react-native';
import axios from 'axios';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as api from '../../constants/api';
import * as moviesActions from './movies.actions';

import styles from './styles/MoviesList';
import CardMovie from './components/CardMovie';
import ProgressBar from '../_global/ProgressBar';

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

		this.state = {
			isLoading: true,
			isRefreshing: false,
			currentPage: 1,
			list: {
				results: []
			}
		};

		this._viewMovie = this._viewMovie.bind(this);
		this._onRefresh = this._onRefresh.bind(this);
	}

	componentWillMount() {
		this._retrieveMoviesList();
	}

	_retrieveMoviesList(isRefreshed) {
		this.props.actions.retrieveMoviesList(this.props.type, this.state.currentPage)
			.then(() => {
				const ds = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
				const dataSource = ds.cloneWithRows(this.props.list.results);
				this.setState({
					list: this.props.list,
					dataSource,
					isLoading: false
				});
			});
		if (isRefreshed && this.setState({ isRefreshing: false }));
	}

	_retrieveNextPage(type) {
		if (this.state.currentPage !== this.props.list.total_page) {
			this.setState({
				currentPage: this.state.currentPage + 1
			});

			let page;
			if (this.state.currentPage === 1) {
				page = 2;
				this.setState({ currentPage: 2 });
			} else {
				page = this.state.currentPage + 1;
			}

			axios.get(`${api.URL}/movie/${type}?api_key=${api.KEY}&page=${page}`)
				.then(res => {
					const data = this.state.list.results;
					const newData = res.data.results;

					newData.map((item, index) => data.push(item));

					this.setState({
						dataSource: this.state.dataSource.cloneWithRows(this.state.list.results)
					});
				}).catch(err => {
					console.log('next page', err); // eslint-disable-line
				});
		}
	}

	_viewMovie(movieId) {
		this.props.navigator.showModal({
			screen: 'movieapp.Movie',
			passProps: {
				movieId
			}
		});
	}

	_onRefresh() {
		this.setState({ isRefreshing: true });
		this._retrieveMoviesList('isRefreshed');
	}

	render() {
		return (this.state.isLoading ? <View style={styles.progressBar}><ProgressBar /></View> :
			<ListView
				style={styles.container}
				enableEmptySections
				onEndReached={type => this._retrieveNextPage(this.props.type)}
				onEndReachedThreshold={1200}
				dataSource={this.state.dataSource}
				renderRow={rowData => <CardMovie info={rowData} viewMovie={this._viewMovie} />}
				renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.seperator} />}
				renderFooter={() => <View style={{ height: 50 }}><ProgressBar /></View>}
				refreshControl={
					<RefreshControl
						refreshing={this.state.isRefreshing}
						onRefresh={this._onRefresh}
						colors={['#EA0000']}
						progressBackgroundColor="white"
					/>
				}
			/>
		);
	}
}

MoviesList.propTypes = {
	actions: PropTypes.object.isRequired,
	list: PropTypes.object.isRequired,
	type: PropTypes.string.isRequired,
	navigator: PropTypes.object
};

MoviesList.navigatorStyle = {
	statusBarColor: 'black',
	statusBarTextColorScheme: 'light',
	navBarBackgroundColor: '#0a0a0a',
	navBarTextColor: 'white',
	navBarButtonColor: 'white'
};

function mapStateToProps(state, ownProps) {
	return {
		list: state.movies.list
	};
}

function mapDispatchToProps(dispatch) {
	return {
		actions: bindActionCreators(moviesActions, dispatch)
	};
}

export default connect(mapStateToProps, mapDispatchToProps)(MoviesList);
<commit_msg>Should be this.props.total_pages<commit_after>import React, { PropTypes, Component } from 'react';
import {
	View,
	ListView,
	RefreshControl
} from 'react-native';
import axios from 'axios';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import * as api from '../../constants/api';
import * as moviesActions from './movies.actions';

import styles from './styles/MoviesList';
import CardMovie from './components/CardMovie';
import ProgressBar from '../_global/ProgressBar';

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

		this.state = {
			isLoading: true,
			isRefreshing: false,
			currentPage: 1,
			list: {
				results: []
			}
		};

		this._viewMovie = this._viewMovie.bind(this);
		this._onRefresh = this._onRefresh.bind(this);
	}

	componentWillMount() {
		this._retrieveMoviesList();
	}

	_retrieveMoviesList(isRefreshed) {
		this.props.actions.retrieveMoviesList(this.props.type, this.state.currentPage)
			.then(() => {
				const ds = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2 });
				const dataSource = ds.cloneWithRows(this.props.list.results);
				this.setState({
					list: this.props.list,
					dataSource,
					isLoading: false
				});
			});
		if (isRefreshed && this.setState({ isRefreshing: false }));
	}

	_retrieveNextPage(type) {
		if (this.state.currentPage !== this.props.list.total_pages) {
			this.setState({
				currentPage: this.state.currentPage + 1
			});

			let page;
			if (this.state.currentPage === 1) {
				page = 2;
				this.setState({ currentPage: 2 });
			} else {
				page = this.state.currentPage + 1;
			}

			axios.get(`${api.URL}/movie/${type}?api_key=${api.KEY}&page=${page}`)
				.then(res => {
					const data = this.state.list.results;
					const newData = res.data.results;

					newData.map((item, index) => data.push(item));

					this.setState({
						dataSource: this.state.dataSource.cloneWithRows(this.state.list.results)
					});
				}).catch(err => {
					console.log('next page', err); // eslint-disable-line
				});
		}
	}

	_viewMovie(movieId) {
		this.props.navigator.showModal({
			screen: 'movieapp.Movie',
			passProps: {
				movieId
			}
		});
	}

	_onRefresh() {
		this.setState({ isRefreshing: true });
		this._retrieveMoviesList('isRefreshed');
	}

	render() {
		return (this.state.isLoading ? <View style={styles.progressBar}><ProgressBar /></View> :
			<ListView
				style={styles.container}
				enableEmptySections
				onEndReached={type => this._retrieveNextPage(this.props.type)}
				onEndReachedThreshold={1200}
				dataSource={this.state.dataSource}
				renderRow={rowData => <CardMovie info={rowData} viewMovie={this._viewMovie} />}
				renderSeparator={(sectionId, rowId) => <View key={rowId} style={styles.seperator} />}
				renderFooter={() => <View style={{ height: 50 }}><ProgressBar /></View>}
				refreshControl={
					<RefreshControl
						refreshing={this.state.isRefreshing}
						onRefresh={this._onRefresh}
						colors={['#EA0000']}
						progressBackgroundColor="white"
					/>
				}
			/>
		);
	}
}

MoviesList.propTypes = {
	actions: PropTypes.object.isRequired,
	list: PropTypes.object.isRequired,
	type: PropTypes.string.isRequired,
	navigator: PropTypes.object
};

MoviesList.navigatorStyle = {
	statusBarColor: 'black',
	statusBarTextColorScheme: 'light',
	navBarBackgroundColor: '#0a0a0a',
	navBarTextColor: 'white',
	navBarButtonColor: 'white'
};

function mapStateToProps(state, ownProps) {
	return {
		list: state.movies.list
	};
}

function mapDispatchToProps(dispatch) {
	return {
		actions: bindActionCreators(moviesActions, dispatch)
	};
}

export default connect(mapStateToProps, mapDispatchToProps)(MoviesList);
<|endoftext|>


<commit_before>'use strict';

(function() {

    angular.module('app').controller('AlunoDetalheController', ['$scope', '$routeParams', 'alunoService', function ($scope, $routeParams, alunoService) {

        // $scope.aluno = {
        //     matricula: $routeParams.numeroMatriculaAluno,
        //     nome: 'Antônio Morrendo das Dores',
        //     dataNascimeno: '18/08/1994',
        //     email: 'antonio@email.com',
        //     fone: '(99) 8877-6655',
        //     estahMatriculado: true,
        //     grade: {
        //         periodo: '2014.2',
        //         cadeiras:[
        //             { descricao: 'Arquitetura de Computadores', creditos: 4, valor: 112.9, status: 'concluido' },
        //             { descricao: 'Lógica de Programação', creditos: 4, valor: 112.9, status: 'concluido' },
        //             { descricao: 'Matemática Discreta', creditos: 4, valor: 112.9, status: 'concluido' },
        //             { descricao: 'Inglês I', creditos: 2, valor: 58.5, status: 'concluido' },
        //             { descricao: 'Inglês II', creditos: 2, valor: 58.5, status: 'cursando' },
        //             { descricao: 'Engenharia de Software', creditos: 4, valor: 112.9, status: 'cursando' },
        //             { descricao: 'Estrutura de Dados', creditos: 4, valor: 112.9, status: 'cursando' },
        //             { descricao: 'Interação Humano Computador', creditos: 2, valor: 58.5, status: 'cursando' },
        //             { descricao: 'Programação OO', creditos: 4, valor: 112.9, status: 'pendente' },
        //             { descricao: 'Banco de Dados', creditos: 4, valor: 58.5, status: 'cursando' },
        //             { descricao: 'Segurança da Informação', creditos: 2, valor: 58.5, status: 'pendente' },
        //             { descricao: 'Empreendedorismo', creditos: 2, valor: 58.5, status: 'pendente' },
        //             { descricao: 'Gestão de Equipes', creditos: 2, valor: 58.5, status: 'pendente' },
        //             { descricao: 'Economia e Finanças', creditos: 2, valor: 58.5, status: 'pendente' },
        //             { descricao: 'Contabilidade', creditos: 2, valor: 58.5, status: 'pendente' },
        //             { descricao: 'Laboratório de Hardware', creditos: 2, valor: 58.5, status: 'pendente' }
        //         ]
        //     }
        // }

        alunoService.obter($routeParams.matricula)
            .success(function (aluno) {
                $scope.aluno = aluno;
            });

    }]);

})();
<commit_msg>retrieve aluno from end-point<commit_after>'use strict';

(function() {

    angular.module('app').controller('AlunoDetalheController', ['$scope', '$routeParams', 'alunoService', function ($scope, $routeParams, alunoService) {

        alunoService.obter($routeParams.matricula)
            .success(function (aluno) {
                $scope.aluno = aluno;
            });

    }]);

})();
<|endoftext|>


<commit_before>// @ts-check

const Lint = require("tslint")
const tsutils = require("tsutils")
const ts = require("typescript")
const { isBinaryExpression } = require("typescript")

const FAILURE_STRING = "Please use safe conditional expressions in JSX 🙏"
class Rule extends Lint.Rules.AbstractRule {
  /**
   * @param {ts.SourceFile} sourceFile
   * @returns {Lint.RuleFailure[]}
   */
  apply(sourceFile) {
    return this.applyWithFunction(sourceFile, walk)
  }
}
module.exports.Rule = Rule

/**
 * @param {ts.Node} node
 */
function isJsxContext(node) {
  if (tsutils.isJsxAttribute(node)) {
    return false
  } else if (tsutils.isJsxElement(node)) {
    return true
  } else {
    if (node.parent) {
      return isJsxContext(node.parent)
    }
  }
}

/**
 * @param {ts.Node} node
 */
function isBooleanExpression(node) {
  return (
    (tsutils.isParenthesizedExpression(node) && isBooleanExpression(node.expression)) ||
    (tsutils.isPrefixUnaryExpression(node) && node.operator == ts.SyntaxKind.ExclamationToken) ||
    (tsutils.isCallExpression(node) && node.expression.getFullText() === "Boolean") ||
    (tsutils.isBinaryExpression(node) &&
      ([
        ts.SyntaxKind.GreaterThanEqualsToken,
        ts.SyntaxKind.GreaterThanToken,
        ts.SyntaxKind.LessThanEqualsToken,
        ts.SyntaxKind.LessThanToken,
        ts.SyntaxKind.EqualsEqualsEqualsToken,
        ts.SyntaxKind.EqualsEqualsToken,
        ts.SyntaxKind.ExclamationEqualsEqualsToken,
        ts.SyntaxKind.ExclamationEqualsToken,
      ].includes(node.operatorToken.kind) ||
        (isBooleanExpression(node.left) && isBooleanExpression(node.right))))
  )
}

/**
 * @param {ts.Node} node
 */
function isWithinBooleanExpression(node) {
  if (node.parent) {
    if (isBooleanExpression(node.parent)) {
      return true
    }
    return isWithinBooleanExpression(node.parent)
  }
  return false
}

/**
 * @param {ts.Node} node
 */
function isOnLeftHandOfConditionalExpression(node) {
  if (node.parent) {
    if (tsutils.isConditionalExpression(node.parent) && node.parent.condition === node) {
      return true
    }
    return isOnLeftHandOfConditionalExpression(node.parent)
  }
  return false
}

/**
 * @param {ts.Node} node
 */
function isInStatementCondition(node) {
  if (node.parent) {
    if (
      (tsutils.isIfStatement(node.parent) || tsutils.isWhileStatement(node.parent)) &&
      node.parent.expression === node
    ) {
      return true
    }
    return isOnLeftHandOfConditionalExpression(node.parent)
  }
  return false
}

/**
 *
 * @param {Lint.WalkContext<void>} ctx
 */
function walk(ctx) {
  /**
   * @param {ts.Node} node
   */
  function cb(node) {
    if (
      tsutils.isBinaryExpression(node) &&
      node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken &&
      isJsxContext(node) &&
      !isBooleanExpression(node.left) &&
      !isWithinBooleanExpression(node) &&
      !isOnLeftHandOfConditionalExpression(node) &&
      !isInStatementCondition(node)
    ) {
      ctx.addFailureAt(
        node.getStart(),
        node.getWidth(),
        FAILURE_STRING,
        new Lint.Replacement(
          node.left.getStart(),
          node.left.getWidth(),
          isBinaryExpression(node.left) ? `!!(${node.left.getFullText()})` : `!!${node.left.getFullText()}`
        )
      )
      return
    }

    return ts.forEachChild(node, cb)
  }

  return ts.forEachChild(ctx.sourceFile, cb)
}
<commit_msg>fix width<commit_after>// @ts-check

const Lint = require("tslint")
const tsutils = require("tsutils")
const ts = require("typescript")
const { isBinaryExpression } = require("typescript")

const FAILURE_STRING = "Please use safe conditional expressions in JSX 🙏"
class Rule extends Lint.Rules.AbstractRule {
  /**
   * @param {ts.SourceFile} sourceFile
   * @returns {Lint.RuleFailure[]}
   */
  apply(sourceFile) {
    return this.applyWithFunction(sourceFile, walk)
  }
}
module.exports.Rule = Rule

/**
 * @param {ts.Node} node
 */
function isJsxContext(node) {
  if (tsutils.isJsxAttribute(node)) {
    return false
  } else if (tsutils.isJsxElement(node)) {
    return true
  } else {
    if (node.parent) {
      return isJsxContext(node.parent)
    }
  }
}

/**
 * @param {ts.Node} node
 */
function isBooleanExpression(node) {
  return (
    (tsutils.isParenthesizedExpression(node) && isBooleanExpression(node.expression)) ||
    (tsutils.isPrefixUnaryExpression(node) && node.operator == ts.SyntaxKind.ExclamationToken) ||
    (tsutils.isCallExpression(node) && node.expression.getFullText() === "Boolean") ||
    (tsutils.isBinaryExpression(node) &&
      ([
        ts.SyntaxKind.GreaterThanEqualsToken,
        ts.SyntaxKind.GreaterThanToken,
        ts.SyntaxKind.LessThanEqualsToken,
        ts.SyntaxKind.LessThanToken,
        ts.SyntaxKind.EqualsEqualsEqualsToken,
        ts.SyntaxKind.EqualsEqualsToken,
        ts.SyntaxKind.ExclamationEqualsEqualsToken,
        ts.SyntaxKind.ExclamationEqualsToken,
      ].includes(node.operatorToken.kind) ||
        (isBooleanExpression(node.left) && isBooleanExpression(node.right))))
  )
}

/**
 * @param {ts.Node} node
 */
function isWithinBooleanExpression(node) {
  if (node.parent) {
    if (isBooleanExpression(node.parent)) {
      return true
    }
    return isWithinBooleanExpression(node.parent)
  }
  return false
}

/**
 * @param {ts.Node} node
 */
function isOnLeftHandOfConditionalExpression(node) {
  if (node.parent) {
    if (tsutils.isConditionalExpression(node.parent) && node.parent.condition === node) {
      return true
    }
    return isOnLeftHandOfConditionalExpression(node.parent)
  }
  return false
}

/**
 * @param {ts.Node} node
 */
function isInStatementCondition(node) {
  if (node.parent) {
    if (
      (tsutils.isIfStatement(node.parent) || tsutils.isWhileStatement(node.parent)) &&
      node.parent.expression === node
    ) {
      return true
    }
    return isOnLeftHandOfConditionalExpression(node.parent)
  }
  return false
}

/**
 *
 * @param {Lint.WalkContext<void>} ctx
 */
function walk(ctx) {
  /**
   * @param {ts.Node} node
   */
  function cb(node) {
    if (
      tsutils.isBinaryExpression(node) &&
      node.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken &&
      isJsxContext(node) &&
      !isBooleanExpression(node.left) &&
      !isWithinBooleanExpression(node) &&
      !isOnLeftHandOfConditionalExpression(node) &&
      !isInStatementCondition(node)
    ) {
      ctx.addFailureAt(
        node.getStart(),
        node.left.getWidth(),
        FAILURE_STRING,
        new Lint.Replacement(
          node.left.getStart(),
          node.left.getWidth(),
          isBinaryExpression(node.left) ? `!!(${node.left.getFullText()})` : `!!${node.left.getFullText()}`
        )
      )
      return
    }

    return ts.forEachChild(node, cb)
  }

  return ts.forEachChild(ctx.sourceFile, cb)
}
<|endoftext|>


<commit_before>/**
 * Module to render the consolidated files view. Reads addon configurrations and
 * initializes an HGrid.
 */
this.Rubeus = (function($, HGrid, bootbox) {

    /////////////////////////
    // HGrid configuration //
    /////////////////////////

    var tpl = HGrid.Fmt.tpl;

    // Override Name column folder view to allow for extra widgets, e.g. github branch picker
    HGrid.Col.Name.folderView = function(item) {
        var html = '';
        if (item.iconUrl)
            html += '';
        else
            html += HGrid.Html.folderIcon;
        html += '' + item.name + '';
        if(item.extra)
            html += '' + item.extra + '';
        return html;
    };

    HGrid.Col.Name.itemView = function(item) {
        var ext = item.name.split('.').pop().toLowerCase();
        return HGrid.Extensions.indexOf(ext) === -1 ?
            HGrid.Html.fileIcon + item.name:
            HGrid.ExtensionSkeleton.replace('{{ext}}', ext) + item.name;
    };

    HGrid.Col.ActionButtons.itemView = function(item) {
      var buttonDefs = [{
          text: '',
          action: 'download',
          cssClass: 'btn btn-primary btn-mini'
      }];
      if (item.permissions && item.permissions.edit) {
          buttonDefs.push({
              text: ' ',
              action: 'delete',
              cssClass: 'btn btn-link btn-mini btn-delete'
          });
      }
      return HGrid.Fmt.buttons(buttonDefs);
    };

    HGrid.Col.ActionButtons.width = 15;
    HGrid.Col.ActionButtons.folderView = function(row) {
        var buttonDefs = [];
        if (this.options.uploads && row.urls.upload &&
            (row.permissions && row.permissions.edit)) {
            buttonDefs.push({
                text: '',
                action: 'upload',
                cssClass: 'btn btn-default btn-mini'
            });
        }
        if (buttonDefs) {
            return HGrid.Fmt.buttons(buttonDefs);
        }
        return '';
    };

    // Custom status column
    HGrid.Col.Status = {
        text: 'Status',
        folderView: '',
        itemView: '',
        width: 50
    };
    HGrid.Html.statusSelector = '[data-status]';

    /**
     * Changes the html in the status column.
     */
    HGrid.prototype.changeStatus = function(row, html, fadeAfter) {
        var rowElem = this.getRowElement(row.id);
        var $status = $(rowElem).find(HGrid.Html.statusSelector);
        $status.html(html);
        if (fadeAfter) {
            setTimeout(function() {
                $status.fadeOut('slow');
            }, fadeAfter);
        }
        return $status;
    };

    // TODO: This should be configurable by addon devs
    var status = {
        FETCH_SUCCESS: '',
        FETCH_START: 'Fetching contents. . .',
        FETCH_ERROR: 'Could not retrieve data. Please refresh the page and try again.',

        UPLOAD_SUCCESS: 'Successfully uploaded',
        NO_CHANGES: 'No changes made from previous version. Removing duplicate row. . .',
        UPDATED: 'Existing file updated. Removing duplicate row. . .',
        DELETING: function(row) {
            return 'Deleting "' + row.name + '"';
        },
        DELETED: function(row) {
            return 'Successfully deleted "' + row.name + '"';
        },
        UPLOAD_ERROR: function(msg) {
            return '' + msg + '';
        },
        UPLOAD_PROGRESS: function(progress) {
            return '' + Math.floor(progress) + '%';
        }
    };

    ////////////////////////
    // Listener callbacks //
    ////////////////////////

    function onConfirmDelete(evt, row, grid) {
        if (row) {
            var rowCopy = $.extend({}, row);
            // Show "Deleting..." message in parent folder's status column
            var parent = grid.getByID(rowCopy.parentID);
            grid.changeStatus(row, status.DELETING(rowCopy));
            grid.deleteFile(row, {
                error: function() {
                    // TODO: This text should be configurable by addon devs
                    bootbox.error('Could not delete ' + row.name + '. Please try again later.');
                },
                success: function() {
                    grid.getDataView().updateItem(parent.id, parent);
                    // Show 'Successfully deleted' in folder's status column
                    grid.changeStatus(row, status.DELETED(rowCopy));
                    setTimeout(function(){
                        grid.removeItem(rowCopy.id);
                    }, 2000);
                }
            });
        }
    }

    function onClickName(evt, row, grid) {
        if (row) {
            var viewUrl = grid.getByID(row.id).urls.view;
            if (viewUrl) {
                window.location.href = viewUrl;
            }
            if (row.kind === HGrid.FOLDER && row.depth !== 0) {
                grid.toggleCollapse(row);
            }
        }
    }

    ///////////////////
    // HGrid options //
    ///////////////////

    // OSF-specific HGrid options common to all addons
    baseOptions = {
        /*jshint unused: false */
        columns: [
            HGrid.Col.Name,
            HGrid.Col.ActionButtons,
            HGrid.Col.Status
        ],
        width: '100%',
        height: 500,
        fetchUrl: function(row) {
            return row.urls.fetch;
        },
        fetchSuccess: function(data, row) {
            this.changeStatus(row, status.FETCH_SUCCESS);
        },
        fetchError: function(error, row) {
            this.changeStatus(row, status.FETCH_ERROR);
        },
        fetchStart: function(row) {
            this.changeStatus(row, status.FETCH_START);
        },
        uploadProgress: function(file, progress, bytesSent, row) {
            this.changeStatus(row, status.UPLOAD_PROGRESS(progress));
        },
        downloadUrl: function(row) {
            return row.urls.download;
        },
        deleteUrl: function(row) {
            return row.urls.delete;
        },
        onClickDelete: function(evt, row) {
            var $elem = $(evt.target);
            // Show inline confirm
            // TODO: Make inline confirmation more reuseable
            $elem.closest('[data-hg-action="delete"]')
                .html('Are you sure? No / Yes');
            return this;
        },
        deleteMethod: 'delete',
        uploads: true,
        maxFilesize: function(row) {
            return row.accept? (row.accept.maxSize || 128) : 128;
        },
        // acceptedFiles: function(row) {
        //     return row.accept.acceptedFiles || null;
        // },
        uploadUrl: function(row) {
            var cfgOption = resolveCfgOption.call(this, row, 'uploadUrl', [row]);
            return cfgOption || row.urls.upload;
        },

        uploadAdded: function(file, row, folder) {
            // Need to set the added row's addon for other callbacks to work
            var parent = this.getByID(row.parentID);
            row.addon = parent.addon;
            // expand the folder
            this.expandItem(folder);
            var cfgOption = resolveCfgOption.call(this, row, 'uploadAdded', [file, row]);
            return cfgOption || null;
        },
        uploadMethod: function(row) {
            var cfgOption = resolveCfgOption.call(this, row, 'uploadMethod', [row]);
            return cfgOption || 'post';
        },
        uploadSending: function(file, row, xhr, formData) {
            var cfgOption = resolveCfgOption.call(this, row, 'uploadSending', [file, row, xhr, formData]);
            return cfgOption || null;
        },
        uploadError: function(file, message, item, folder) {
            // FIXME: can't use change status, because the folder item is updated
            // on complete, which replaces the html row element
            // for now, use bootbox
            bootbox.alert(message);
        },
        uploadSuccess: function(file, row, data) {
            // If file hasn't changed, remove the duplicate item
            // TODO: shows status in parent for now because the duplicate item
            // is removed and we don't have access to the original row for the file
            var self = this;
            if (data.actionTaken === null) {
                self.changeStatus(row, status.NO_CHANGES);
                setTimeout(function() {
                    $(self.getRowElement(row)).fadeOut(500, function() {
                        self.removeItem(row.id);
                    });
                }, 2000);
            } else if (data.actionTaken === 'file_updated') {
                self.changeStatus(row, status.UPDATED);
                setTimeout(function() {
                    $(self.getRowElement(row)).fadeOut(500, function() {
                        self.removeItem(row.id);
                    });
                }, 2000);
            } else{
                // Update the row with the returned server data
                // This is necessary for the download and delete button to work.
                $.extend(row, data);
                this.updateItem(row);
                this.changeStatus(row, status.UPLOAD_SUCCESS, 2000);
            }
            var cfgOption = resolveCfgOption.call(this, row, 'uploadSuccess', [file, row, data]);
            return cfgOption || null;
        },
        // TODO: Set parallel uploads to 1 for now until git collision issue is fixed
        dropzoneOptions: {
            parallelUploads: 1
        },
        listeners: [
            // Go to file's detail page if name is clicked
            {
                on: 'click',
                selector: '.' + HGrid.Html.nameClass,
                callback: onClickName
            }, {
                on: 'click',
                selector: '.confirm',
                callback: onConfirmDelete
            }, {
                on: 'click',
                selector: '.unconfirm',
                callback: function(evt, row, grid) {
                    if (row) {
                        // restore row html
                        grid.updateItem(row);
                    }
                }
            }
        ],
        init: function() {
            var self = this;
            // Expand all first level items
            this.getData().forEach(function(item) {
                self.expandItem(item);
            });
        }
    };

    ///////////////////////
    // Rubeus Public API //
    ///////////////////////

    function Rubeus(selector, options) {
        this.selector = selector;
        this.options = $.extend({}, baseOptions, options);
        this.grid = null; // Set by _initGrid
        this.init();
    }
    // Addon config registry
    Rubeus.cfg = {};

    function getCfg(row, key) {
        if (row && row.addon && Rubeus.cfg[row.addon]) {
            return Rubeus.cfg[row.addon][key];
        }
        return undefined;
    }

    // Gets a Rubeus config option if it is defined by an addon dev.
    // Calls it with `args` if it's a function otherwise returns the value.
    // If the config option is not defined, return null
    function resolveCfgOption(row, option, args) {
        var self = this;
        var prop = getCfg(row, option);
        if (prop) {
            return typeof prop === 'function' ? prop.apply(self, args) : prop;
        } else {
            return null;
        }
    }

    Rubeus.prototype = {
        constructor: Rubeus,
        init: function() {
            this._registerListeners()
                ._initGrid();
        },
        _registerListeners: function() {
            for (var addon in Rubeus.cfg) {
                var listeners = Rubeus.cfg[addon].listeners;
                if (listeners) {
                    // Add each listener to the hgrid options
                    for (var i = 0, listener; listener = listeners[i]; i++) {
                        this.options.listeners.push(listener);
                    }
                }
            }
            return this;
        },
        // Create the Hgrid once all addons have been configured
        _initGrid: function() {
            this.grid = new HGrid(this.selector, this.options);
            return this;
        }
    };

    return Rubeus;

})(jQuery, HGrid, bootbox);
<commit_msg>Decrease delay after deleting<commit_after>/**
 * Module to render the consolidated files view. Reads addon configurrations and
 * initializes an HGrid.
 */
this.Rubeus = (function($, HGrid, bootbox) {

    /////////////////////////
    // HGrid configuration //
    /////////////////////////

    var tpl = HGrid.Fmt.tpl;

    // Override Name column folder view to allow for extra widgets, e.g. github branch picker
    HGrid.Col.Name.folderView = function(item) {
        var html = '';
        if (item.iconUrl)
            html += '';
        else
            html += HGrid.Html.folderIcon;
        html += '' + item.name + '';
        if(item.extra)
            html += '' + item.extra + '';
        return html;
    };

    HGrid.Col.Name.itemView = function(item) {
        var ext = item.name.split('.').pop().toLowerCase();
        return HGrid.Extensions.indexOf(ext) === -1 ?
            HGrid.Html.fileIcon + item.name:
            HGrid.ExtensionSkeleton.replace('{{ext}}', ext) + item.name;
    };

    HGrid.Col.ActionButtons.itemView = function(item) {
      var buttonDefs = [{
          text: '',
          action: 'download',
          cssClass: 'btn btn-primary btn-mini'
      }];
      if (item.permissions && item.permissions.edit) {
          buttonDefs.push({
              text: ' ',
              action: 'delete',
              cssClass: 'btn btn-link btn-mini btn-delete'
          });
      }
      return HGrid.Fmt.buttons(buttonDefs);
    };

    HGrid.Col.ActionButtons.width = 15;
    HGrid.Col.ActionButtons.folderView = function(row) {
        var buttonDefs = [];
        if (this.options.uploads && row.urls.upload &&
            (row.permissions && row.permissions.edit)) {
            buttonDefs.push({
                text: '',
                action: 'upload',
                cssClass: 'btn btn-default btn-mini'
            });
        }
        if (buttonDefs) {
            return HGrid.Fmt.buttons(buttonDefs);
        }
        return '';
    };

    // Custom status column
    HGrid.Col.Status = {
        text: 'Status',
        folderView: '',
        itemView: '',
        width: 50
    };
    HGrid.Html.statusSelector = '[data-status]';

    /**
     * Changes the html in the status column.
     */
    HGrid.prototype.changeStatus = function(row, html, fadeAfter) {
        var rowElem = this.getRowElement(row.id);
        var $status = $(rowElem).find(HGrid.Html.statusSelector);
        $status.html(html);
        if (fadeAfter) {
            setTimeout(function() {
                $status.fadeOut('slow');
            }, fadeAfter);
        }
        return $status;
    };

    // TODO: This should be configurable by addon devs
    var status = {
        FETCH_SUCCESS: '',
        FETCH_START: 'Fetching contents. . .',
        FETCH_ERROR: 'Could not retrieve data. Please refresh the page and try again.',

        UPLOAD_SUCCESS: 'Successfully uploaded',
        NO_CHANGES: 'No changes made from previous version. Removing duplicate row. . .',
        UPDATED: 'Existing file updated. Removing duplicate row. . .',
        DELETING: function(row) {
            return 'Deleting "' + row.name + '"';
        },
        DELETED: function(row) {
            return 'Successfully deleted "' + row.name + '"';
        },
        UPLOAD_ERROR: function(msg) {
            return '' + msg + '';
        },
        UPLOAD_PROGRESS: function(progress) {
            return '' + Math.floor(progress) + '%';
        }
    };

    ////////////////////////
    // Listener callbacks //
    ////////////////////////

    function onConfirmDelete(evt, row, grid) {
        if (row) {
            var rowCopy = $.extend({}, row);
            // Show "Deleting..." message in parent folder's status column
            var parent = grid.getByID(rowCopy.parentID);
            grid.changeStatus(row, status.DELETING(rowCopy));
            grid.deleteFile(row, {
                error: function() {
                    // TODO: This text should be configurable by addon devs
                    bootbox.error('Could not delete ' + row.name + '. Please try again later.');
                },
                success: function() {
                    grid.getDataView().updateItem(parent.id, parent);
                    // Show 'Successfully deleted' in folder's status column
                    grid.changeStatus(row, status.DELETED(rowCopy));
                    setTimeout(function(){
                        grid.removeItem(rowCopy.id);
                    }, 1000);
                }
            });
        }
    }

    function onClickName(evt, row, grid) {
        if (row) {
            var viewUrl = grid.getByID(row.id).urls.view;
            if (viewUrl) {
                window.location.href = viewUrl;
            }
            if (row.kind === HGrid.FOLDER && row.depth !== 0) {
                grid.toggleCollapse(row);
            }
        }
    }

    ///////////////////
    // HGrid options //
    ///////////////////

    // OSF-specific HGrid options common to all addons
    baseOptions = {
        /*jshint unused: false */
        columns: [
            HGrid.Col.Name,
            HGrid.Col.ActionButtons,
            HGrid.Col.Status
        ],
        width: '100%',
        height: 500,
        fetchUrl: function(row) {
            return row.urls.fetch;
        },
        fetchSuccess: function(data, row) {
            this.changeStatus(row, status.FETCH_SUCCESS);
        },
        fetchError: function(error, row) {
            this.changeStatus(row, status.FETCH_ERROR);
        },
        fetchStart: function(row) {
            this.changeStatus(row, status.FETCH_START);
        },
        uploadProgress: function(file, progress, bytesSent, row) {
            this.changeStatus(row, status.UPLOAD_PROGRESS(progress));
        },
        downloadUrl: function(row) {
            return row.urls.download;
        },
        deleteUrl: function(row) {
            return row.urls.delete;
        },
        onClickDelete: function(evt, row) {
            var $elem = $(evt.target);
            // Show inline confirm
            // TODO: Make inline confirmation more reuseable
            $elem.closest('[data-hg-action="delete"]')
                .html('Are you sure? No / Yes');
            return this;
        },
        deleteMethod: 'delete',
        uploads: true,
        maxFilesize: function(row) {
            return row.accept? (row.accept.maxSize || 128) : 128;
        },
        // acceptedFiles: function(row) {
        //     return row.accept.acceptedFiles || null;
        // },
        uploadUrl: function(row) {
            var cfgOption = resolveCfgOption.call(this, row, 'uploadUrl', [row]);
            return cfgOption || row.urls.upload;
        },

        uploadAdded: function(file, row, folder) {
            // Need to set the added row's addon for other callbacks to work
            var parent = this.getByID(row.parentID);
            row.addon = parent.addon;
            // expand the folder
            this.expandItem(folder);
            var cfgOption = resolveCfgOption.call(this, row, 'uploadAdded', [file, row]);
            return cfgOption || null;
        },
        uploadMethod: function(row) {
            var cfgOption = resolveCfgOption.call(this, row, 'uploadMethod', [row]);
            return cfgOption || 'post';
        },
        uploadSending: function(file, row, xhr, formData) {
            var cfgOption = resolveCfgOption.call(this, row, 'uploadSending', [file, row, xhr, formData]);
            return cfgOption || null;
        },
        uploadError: function(file, message, item, folder) {
            // FIXME: can't use change status, because the folder item is updated
            // on complete, which replaces the html row element
            // for now, use bootbox
            bootbox.alert(message);
        },
        uploadSuccess: function(file, row, data) {
            // If file hasn't changed, remove the duplicate item
            // TODO: shows status in parent for now because the duplicate item
            // is removed and we don't have access to the original row for the file
            var self = this;
            if (data.actionTaken === null) {
                self.changeStatus(row, status.NO_CHANGES);
                setTimeout(function() {
                    $(self.getRowElement(row)).fadeOut(500, function() {
                        self.removeItem(row.id);
                    });
                }, 2000);
            } else if (data.actionTaken === 'file_updated') {
                self.changeStatus(row, status.UPDATED);
                setTimeout(function() {
                    $(self.getRowElement(row)).fadeOut(500, function() {
                        self.removeItem(row.id);
                    });
                }, 2000);
            } else{
                // Update the row with the returned server data
                // This is necessary for the download and delete button to work.
                $.extend(row, data);
                this.updateItem(row);
                this.changeStatus(row, status.UPLOAD_SUCCESS, 2000);
            }
            var cfgOption = resolveCfgOption.call(this, row, 'uploadSuccess', [file, row, data]);
            return cfgOption || null;
        },
        // TODO: Set parallel uploads to 1 for now until git collision issue is fixed
        dropzoneOptions: {
            parallelUploads: 1
        },
        listeners: [
            // Go to file's detail page if name is clicked
            {
                on: 'click',
                selector: '.' + HGrid.Html.nameClass,
                callback: onClickName
            }, {
                on: 'click',
                selector: '.confirm',
                callback: onConfirmDelete
            }, {
                on: 'click',
                selector: '.unconfirm',
                callback: function(evt, row, grid) {
                    if (row) {
                        // restore row html
                        grid.updateItem(row);
                    }
                }
            }
        ],
        init: function() {
            var self = this;
            // Expand all first level items
            this.getData().forEach(function(item) {
                self.expandItem(item);
            });
        }
    };

    ///////////////////////
    // Rubeus Public API //
    ///////////////////////

    function Rubeus(selector, options) {
        this.selector = selector;
        this.options = $.extend({}, baseOptions, options);
        this.grid = null; // Set by _initGrid
        this.init();
    }
    // Addon config registry
    Rubeus.cfg = {};

    function getCfg(row, key) {
        if (row && row.addon && Rubeus.cfg[row.addon]) {
            return Rubeus.cfg[row.addon][key];
        }
        return undefined;
    }

    // Gets a Rubeus config option if it is defined by an addon dev.
    // Calls it with `args` if it's a function otherwise returns the value.
    // If the config option is not defined, return null
    function resolveCfgOption(row, option, args) {
        var self = this;
        var prop = getCfg(row, option);
        if (prop) {
            return typeof prop === 'function' ? prop.apply(self, args) : prop;
        } else {
            return null;
        }
    }

    Rubeus.prototype = {
        constructor: Rubeus,
        init: function() {
            this._registerListeners()
                ._initGrid();
        },
        _registerListeners: function() {
            for (var addon in Rubeus.cfg) {
                var listeners = Rubeus.cfg[addon].listeners;
                if (listeners) {
                    // Add each listener to the hgrid options
                    for (var i = 0, listener; listener = listeners[i]; i++) {
                        this.options.listeners.push(listener);
                    }
                }
            }
            return this;
        },
        // Create the Hgrid once all addons have been configured
        _initGrid: function() {
            this.grid = new HGrid(this.selector, this.options);
            return this;
        }
    };

    return Rubeus;

})(jQuery, HGrid, bootbox);
<|endoftext|>


<commit_before>module.exports = function (grunt) {
    'use strict';
    var fs = require('fs');
    var yaml = require('yamljs');

    grunt.registerMultiTask('swagger-js-codegen', 'Swagger codegen for Javascript', function(){
        var request = require('request');
        var Q = require('q');
        var _ = require('lodash');

        var options = this.options();
        var dest = options.dest;
        var promises = [];
        var done = this.async();

        grunt.file.mkdir(dest);
        options.apis.forEach(function(api){
            var deferred = Q.defer();
            var fname = api.fileName || (api.moduleName || api.className) + '.js';
            if(api.swagger.substring(0, 'http://'.length) === 'http://' || api.swagger.substring(0, 'https://'.length) === 'https://') {
                request({
                    uri: api.swagger,
                    method: 'GET'
                }, function(error, response, body){
                    if(error || response.statusCode !== 200) {
                        deferred.reject('Error while fetching ' + api.swagger + ': ' + (error || body));
                    } else {
                        var swagger = JSON.parse(body);
                        generateApi(api, swagger, dest, fname);
                        deferred.resolve();
                    }
                });
            } else if(testIfYamlExtension(api.swagger)) {
                fs.readFile(api.swagger, 'UTF-8', function(err, data) {
                    if(err) {
                        deferred.reject(err);
                    } else {
                        var swagger = yaml.parse(data);
                        generateApi(api, swagger, dest, fname);
                        deferred.resolve();
                    }
                });
            } else {
                fs.readFile(api.swagger, 'UTF-8', function(err, data){
                    if(err) {
                        deferred.reject(err);
                    } else {
                        var swagger = JSON.parse(data);
                        generateApi(api, swagger, dest, fname);
                        deferred.resolve();
                    }
                });
            }
            promises.push(deferred.promise);
        });
        Q.all(promises).then(function(){
            done();
        }).catch(function(error){
            var e;
            if(_.isObject(error) && error.body) {
                e = JSON.stringify(error.body, null, 2);
            } else if(_.isObject(error)) {
                e = JSON.stringify(error, null, 2);
            } else if(error instanceof Error || _.isString(error)) {
                e = error;
            } else {
                e = new Error('Unknown error');
            }
            grunt.fail.fatal(e);
        });
    });

    function testIfYamlExtension(filename) {
        return filename.substring(filename.length - '.yaml'.length) === '.yaml' || filename.substring(filename.length - '.yml'.length) === '.yml';
    }

    function generateApi(api, swagger, dest, fname) {
        var CodeGen = require('swagger-js-codegen').CodeGen;
        var source = null;

        if (api.type === 'angular' || api.angularjs === true) {
            source = CodeGen.getAngularCode({ moduleName: api.moduleName, className: api.className, swagger: swagger });
        } else if (api.custom === true) {
            source = CodeGen.getCustomCode({ className: api.className, swagger: swagger, mustache: api.mustache,
                template: {
                    class: fs.readFileSync(api.template.class, 'utf-8'),
                    method: fs.readFileSync(api.template.method, 'utf-8'),
                    request: fs.readFileSync(api.template.request, 'utf-8')
                }
            });
        } else {
            source = CodeGen.getNodeCode({ className: api.className, swagger: swagger });
        }
        grunt.log.writeln('Generated ' + fname + ' from ' + api.swagger);
        fs.writeFileSync(dest + '/' + fname, source, 'UTF-8');
    }
};
<commit_msg>Fix issue when the file name was written in uppercase<commit_after>module.exports = function (grunt) {
    'use strict';
    var fs = require('fs');
    var yaml = require('yamljs');

    grunt.registerMultiTask('swagger-js-codegen', 'Swagger codegen for Javascript', function(){
        var request = require('request');
        var Q = require('q');
        var _ = require('lodash');

        var options = this.options();
        var dest = options.dest;
        var promises = [];
        var done = this.async();

        grunt.file.mkdir(dest);
        options.apis.forEach(function(api){
            var deferred = Q.defer();
            var fname = api.fileName || (api.moduleName || api.className) + '.js';
            if(api.swagger.substring(0, 'http://'.length) === 'http://' || api.swagger.substring(0, 'https://'.length) === 'https://') {
                request({
                    uri: api.swagger,
                    method: 'GET'
                }, function(error, response, body){
                    if(error || response.statusCode !== 200) {
                        deferred.reject('Error while fetching ' + api.swagger + ': ' + (error || body));
                    } else {
                        var swagger = JSON.parse(body);
                        generateApi(api, swagger, dest, fname);
                        deferred.resolve();
                    }
                });
            } else if(testIfYamlExtension(api.swagger)) {
                fs.readFile(api.swagger, 'UTF-8', function(err, data) {
                    if(err) {
                        deferred.reject(err);
                    } else {
                        var swagger = yaml.parse(data);
                        generateApi(api, swagger, dest, fname);
                        deferred.resolve();
                    }
                });
            } else {
                fs.readFile(api.swagger, 'UTF-8', function(err, data){
                    if(err) {
                        deferred.reject(err);
                    } else {
                        var swagger = JSON.parse(data);
                        generateApi(api, swagger, dest, fname);
                        deferred.resolve();
                    }
                });
            }
            promises.push(deferred.promise);
        });
        Q.all(promises).then(function(){
            done();
        }).catch(function(error){
            var e;
            if(_.isObject(error) && error.body) {
                e = JSON.stringify(error.body, null, 2);
            } else if(_.isObject(error)) {
                e = JSON.stringify(error, null, 2);
            } else if(error instanceof Error || _.isString(error)) {
                e = error;
            } else {
                e = new Error('Unknown error');
            }
            grunt.fail.fatal(e);
        });
    });

    function testIfYamlExtension(filename) {
        return filename.substring(filename.length - '.yaml'.length).toLowerCase() === '.yaml' || filename.substring(filename.length - '.yml'.length).toLowerCase() === '.yml';
    }

    function generateApi(api, swagger, dest, fname) {
        var CodeGen = require('swagger-js-codegen').CodeGen;
        var source = null;

        if (api.type === 'angular' || api.angularjs === true) {
            source = CodeGen.getAngularCode({ moduleName: api.moduleName, className: api.className, swagger: swagger });
        } else if (api.custom === true) {
            source = CodeGen.getCustomCode({ className: api.className, swagger: swagger, mustache: api.mustache,
                template: {
                    class: fs.readFileSync(api.template.class, 'utf-8'),
                    method: fs.readFileSync(api.template.method, 'utf-8'),
                    request: fs.readFileSync(api.template.request, 'utf-8')
                }
            });
        } else {
            source = CodeGen.getNodeCode({ className: api.className, swagger: swagger });
        }
        grunt.log.writeln('Generated ' + fname + ' from ' + api.swagger);
        fs.writeFileSync(dest + '/' + fname, source, 'UTF-8');
    }
};
<|endoftext|>


<commit_before>function GM_openInTab(_url) {
  self.port.emit("GM_openInTab", _url);
};

function GM_setValue(_name, _value) {
  localStorage[_name] = _value;
};

function GM_getValue(_name, _default) {
  if (localStorage[_name] === null && _default === null) return undefined;
  return localStorage[_name] || _default;
};

function GM_deleteValue(_name) {
  localStorage.removeItem(_name);
};

function GM_listValues() {
  return Object.keys(localStorage);
};

function GM_setClipboard(_text) {
//   Break on Firefox mobile
//   self.port.emit("GM_setClipboard", _text);
};

//Deprecated
function GM_log(_message) {
  console.log(_message);
};

function GM_xmlhttpRequest(_details) {
  //Ugly hack? Race condition? Memory leak?
  _onload = _details.onload;
  _context = _details.context;
  self.port.emit("GM_xmlhttpRequest", _details);
};

self.port.on("callback_GM_xmlhttpRequest", function(_response) {
  _response.context = _context;
  _onload(_response);
});

function GM_addStyle(_css) {
  self.port.emit("GM_addStyle", _css);
}

var GM_info = new Object();
GM_info.version = '1.15';
GM_info.scriptWillUpdate = true;

//To do
function GM_registerMenuCommand(_caption, _commandFunc, _accessKey) {
  return null;
}

self.port.on("load-userscript", function(_script) {
  eval(_script);
});<commit_msg>Update greaseshim.js<commit_after>function GM_openInTab(_url) {
  self.port.emit("GM_openInTab", _url);
  return; // Should return the Window object
};

function GM_setValue(_name, _value) {
  localStorage[_name] = _value;
  return;
};

function GM_getValue(_name, _default) {
  if (localStorage[_name] === null && _default === null) return;
  return localStorage[_name] || _default;
};

function GM_deleteValue(_name) {
  localStorage.removeItem(_name);
  return;
};

function GM_listValues() {
  return Object.keys(localStorage);
};

function GM_setClipboard(_text) {
//   Break on Firefox mobile
//   self.port.emit("GM_setClipboard", _text);
};

//Deprecated
function GM_log(_message) {
  console.log(_message);
  return;
};

function GM_xmlhttpRequest(_details) {
  //Ugly hack? Race condition? Memory leak?
  _onload = _details.onload;
  _context = _details.context;
  self.port.emit("GM_xmlhttpRequest", _details);
};

self.port.on("callback_GM_xmlhttpRequest", function(_response) {
  _response.context = _context;
  _onload(_response);
});

function GM_addStyle(_css) {
  self.port.emit("GM_addStyle", _css);
}

var GM_info = new Object();
GM_info.version = '1.15';
GM_info.scriptWillUpdate = true;

//To do
function GM_registerMenuCommand(_caption, _commandFunc, _accessKey) {
  return;
}

self.port.on("load-userscript", function(_script) {
  eval(_script);
});
<|endoftext|>


<commit_before>var tape = require("tape");
var jsdom = require("./jsdom");
var deepEqualData = require("./deepEqualData");
var d3 = require("d3-selection");
var d3_graphviz = require("../");
var translatePointsAttribute = require("./svg").translatePointsAttribute;

tape("Verify that rect shape is drawn exactly as Graphviz does.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var expectedGraph = d3.select("#expected-graph");
    var actualGraph = d3.select("#actual-graph");
    var expectedGraphviz = d3_graphviz.graphviz("#expected-graph");
    var actualGraphviz = d3_graphviz.graphviz("#actual-graph");

    expectedGraphviz
        .zoom(false)
        .renderDot('digraph {a [shape="rect"]}', function () {
            actualGraphviz
                .renderDot('digraph {}', function () {
                    var x = 27;
                    var y = -18;
                    actualGraphviz
                        .drawNode(x, y, 'a', {shape: 'rect', id: 'node1'})
                        .insertDrawnNode('a');

                    expectedNodeGroup = expectedGraph.selectAll('.node');
                    expectedNodeTitle = expectedNodeGroup.selectAll('title');
                    expectedNodeShape = expectedNodeGroup.selectAll('polygon');
                    expectedNodeText = expectedNodeGroup.selectAll('text');

                    actualNodeGroup = actualGraph.selectAll('.node');
                    actualNodeTitle = actualNodeGroup.selectAll('title');
                    actualNodeShape = actualNodeGroup.selectAll('polygon');
                    actualNodeText = actualNodeGroup.selectAll('text');

                    var bbox = expectedNodeShape.node().getBBox();
                    bbox.cx = bbox.x + bbox.width / 2;
                    bbox.cy = bbox.y + bbox.height / 2;
                    xoffs = x - bbox.cx;
                    yoffs = y - bbox.cy;

                    test.equal(actualNodeGroup.attr("id"), expectedNodeGroup.attr("id"), 'id of group');

                    test.equal(actualNodeTitle.text(), expectedNodeTitle.text(), 'text of title');

                    test.equal(actualNodeShape.attr("fill"), expectedNodeShape.attr("fill"), 'fill of polygon');
                    test.equal(actualNodeShape.attr("stroke"), expectedNodeShape.attr("stroke"), 'stroke of polygon');
                    test.equal(actualNodeShape.attr("points"), translatePointsAttribute(expectedNodeShape.attr("points"), xoffs, yoffs), 'points of polygon');

                    test.equal(actualNodeText.attr("text-anchor"), expectedNodeText.attr("text-anchor"), 'text-anchor of text');
                    test.equal(+actualNodeText.attr("x"), +expectedNodeText.attr("x") + xoffs, 'x of text');
                    test.equal(+actualNodeText.attr("y"), +expectedNodeText.attr("y") + yoffs, 'y of text');
                    test.equal(actualNodeText.attr("font-family"), expectedNodeText.attr("font-family"), 'font-family of text');
                    test.equal(actualNodeText.attr("font-size"), expectedNodeText.attr("font-size"), 'font-size of text');
                    test.equal(actualNodeText.attr("fill"), expectedNodeText.attr("fill"), 'fill of text');

                    test.equal(actualNodeText.text(), expectedNodeText.text(), 'text of node group');

                    var actualNodeGroupDatum = actualNodeGroup.datum();
                    var expectedNodeGroupDatum = expectedNodeGroup.datum();
                    delete expectedNodeGroupDatum.parent;
                    deepEqualData(test, actualNodeGroupDatum, expectedNodeGroupDatum, 'data of drawn node of shape equals Graphviz generated data');

                    test.end();
                });
        });
});
<commit_msg>Port drawNode-shape-rect-test.js to hpcc-js-wasm<commit_after>var tape = require("tape");
var jsdom = require("./jsdom");
var deepEqualData = require("./deepEqualData");
var d3 = require("d3-selection");
var d3_graphviz = require("../");
var translatePointsAttribute = require("./svg").translatePointsAttribute;

tape("Verify that rect shape is drawn exactly as Graphviz does.", function(test) {
    var window = global.window = jsdom('

');
    var document = global.document = window.document;
    var expectedGraph = d3.select("#expected-graph");
    var actualGraph = d3.select("#actual-graph");
    var actualGraphviz;
    var expectedGraphviz = d3_graphviz.graphviz("#expected-graph")
        .on('initEnd', () => {
            actualGraphviz = d3_graphviz.graphviz("#actual-graph")
                .on('initEnd', startTest);
        });

    function startTest() {
    expectedGraphviz
        .zoom(false)
        .renderDot('digraph {a [shape="rect"]}', function () {
            actualGraphviz
                .renderDot('digraph {}', function () {
                    var x = 27;
                    var y = -18;
                    actualGraphviz
                        .drawNode(x, y, 'a', {shape: 'rect', id: 'node1'})
                        .insertDrawnNode('a');

                    expectedNodeGroup = expectedGraph.selectAll('.node');
                    expectedNodeTitle = expectedNodeGroup.selectAll('title');
                    expectedNodeShape = expectedNodeGroup.selectAll('polygon');
                    expectedNodeText = expectedNodeGroup.selectAll('text');

                    actualNodeGroup = actualGraph.selectAll('.node');
                    actualNodeTitle = actualNodeGroup.selectAll('title');
                    actualNodeShape = actualNodeGroup.selectAll('polygon');
                    actualNodeText = actualNodeGroup.selectAll('text');

                    var bbox = expectedNodeShape.node().getBBox();
                    bbox.cx = bbox.x + bbox.width / 2;
                    bbox.cy = bbox.y + bbox.height / 2;
                    xoffs = x - bbox.cx;
                    yoffs = y - bbox.cy;

                    test.equal(actualNodeGroup.attr("id"), expectedNodeGroup.attr("id"), 'id of group');

                    test.equal(actualNodeTitle.text(), expectedNodeTitle.text(), 'text of title');

                    test.equal(actualNodeShape.attr("fill"), expectedNodeShape.attr("fill"), 'fill of polygon');
                    test.equal(actualNodeShape.attr("stroke"), expectedNodeShape.attr("stroke"), 'stroke of polygon');
                    test.equal(actualNodeShape.attr("points"), translatePointsAttribute(expectedNodeShape.attr("points"), xoffs, yoffs), 'points of polygon');

                    test.equal(actualNodeText.attr("text-anchor"), expectedNodeText.attr("text-anchor"), 'text-anchor of text');
                    test.equal(+actualNodeText.attr("x"), +expectedNodeText.attr("x") + xoffs, 'x of text');
                    test.equal(+actualNodeText.attr("y"), +expectedNodeText.attr("y") + yoffs, 'y of text');
                    test.equal(actualNodeText.attr("font-family"), expectedNodeText.attr("font-family"), 'font-family of text');
                    test.equal(actualNodeText.attr("font-size"), expectedNodeText.attr("font-size"), 'font-size of text');
                    test.equal(actualNodeText.attr("fill"), expectedNodeText.attr("fill"), 'fill of text');

                    test.equal(actualNodeText.text(), expectedNodeText.text(), 'text of node group');

                    var actualNodeGroupDatum = actualNodeGroup.datum();
                    var expectedNodeGroupDatum = expectedNodeGroup.datum();
                    delete expectedNodeGroupDatum.parent;
                    deepEqualData(test, actualNodeGroupDatum, expectedNodeGroupDatum, 'data of drawn node of shape equals Graphviz generated data');

                    test.end();
                });
        });
    }
});
<|endoftext|>