<commit_before>/**
 * The UI Element for exporting pedigrees
 *
 * @class ExportSelector
 */
define([
        "pedigree/filesaver/FileSaver",
        "pedigree/model/export"
    ], function(
        FileSaver,
        PedigreeExport
    ){
    var ExportSelector = Class.create( {

        initialize: function() {
            var _this = this;

            var mainDiv = new Element('div', {'class': 'export-selector'});

            var _addTypeOption = function (checked, labelText, value) {
                var optionWrapper = new Element('tr');
                var input = new Element('input', {"type" : "radio", "value": value, "name": "export-type"});
                input.observe('click', _this.disableEnableOptions );
                if (checked) {
                  input.checked = true;
                }
                var label = new Element('label', {'class': 'import-type-label'}).insert(input).insert(labelText);
                optionWrapper.insert(label.wrap('td'));
                return optionWrapper;
              };
            var typeListElement = new Element('table');
            typeListElement.insert(_addTypeOption(true,  "PED", "ped"));
            typeListElement.insert(_addTypeOption(false, "BOADICEA", "BOADICEA"));
            typeListElement.insert(_addTypeOption(false, "Simple JSON", "simpleJSON"));
            typeListElement.insert(_addTypeOption(false, "Image", "image"));
            //TODO: typeListElement.insert(_addTypeOption(false, "Phenotips Pedigree JSON", "phenotipsJSON"));

            var fileDownload = new Element('a', {"id": 'downloadLink', "style": 'display:none'});
            mainDiv.insert(fileDownload);

            var promptType = new Element('div', {'class': 'import-section'}).update("Data format:");
            var dataSection2 = new Element('div', {'class': 'import-block'});
            dataSection2.insert(promptType).insert(typeListElement);
            mainDiv.insert(dataSection2);

            var configListElementJSON = new Element('table', {"id": "jsonOptions", "style": 'display:none'});
            configListElementJSON.insert(this._addConfigOption(true,  "export-options", "import-config-label", "All data", "all"));
            configListElementJSON.insert(this._addConfigOption(false, "export-options", "import-config-label", "Remove personal information (name and age)", "nopersonal"));
            configListElementJSON.insert(this._addConfigOption(false, "export-options", "import-config-label", "Remove personal information and free-form comments", "minimal"));

            var configListElementPED = new Element('table', {"id": "pedOptions"});
            var label = new Element('label', {'class': 'export-config-header'}).insert("How should person IDs be assigned in the generated file?");
            configListElementPED.insert(label.wrap('td').wrap('tr'));
            configListElementPED.insert(this._addConfigOption(true,  "ped-options", "export-subconfig-label", "Using External IDs (when available)", "external"));
            configListElementPED.insert(this._addConfigOption(false, "ped-options", "export-subconfig-label", "Generate new numeric IDs", "newid"));
            configListElementPED.insert(this._addConfigOption(false, "ped-options", "export-subconfig-label", "Using Names (when available)", "name"));

            var configListElementImage = new Element('table', {"id": "imageOptions", "style": 'display:none'});
            var label = new Element('label', {'class': 'export-config-header'}).insert("Select type of generated pedigree image");
            configListElementImage.insert(label.wrap('td').wrap('tr'));
            configListElementImage.insert(this._addConfigOption(true,  "image-options", "export-subconfig-label", "Raster image (PNG)", "png"));
            configListElementImage.insert(this._addConfigOption(false, "image-options", "export-subconfig-label", "Scalable image (SVG)", "svg"));

            var promptConfig = new Element('div', {'class': 'import-section'}).update("Options:");
            var dataSection3 = new Element('div', {'class': 'import-block'});
            dataSection3.insert(promptConfig).insert(configListElementJSON).insert(configListElementPED).insert(configListElementImage);
            mainDiv.insert(dataSection3);

            var buttons = new Element('div', {'class' : 'buttons import-block-bottom'});
            buttons.insert(new Element('input', {type: 'button', name : 'export', 'value': 'Export', 'class' : 'button', 'id': 'export_button'}).wrap('span', {'class' : 'buttonwrapper'}));
            buttons.insert(new Element('input', {type: 'button', name : 'cancel', 'value': 'Cancel', 'class' : 'button secondary'}).wrap('span', {'class' : 'buttonwrapper'}));
            mainDiv.insert(buttons);

            var cancelButton = buttons.down('input[name="cancel"]');
            cancelButton.observe('click', function(event) {
                _this.hide();
            })
            var exportButton = buttons.down('input[name="export"]');
            exportButton.observe('click', function(event) {
                _this._onExportStarted();
            })

            var closeShortcut = ['Esc'];
            this.dialog = new PhenoTips.widgets.ModalPopup(mainDiv, {close: {method : this.hide.bind(this), keys : closeShortcut}}, {extraClassName: "pedigree-import-chooser", title: "Pedigree export", displayCloseButton: true});
        },

        /*
         * Disables unapplicable options on input type selection
         */
        disableEnableOptions: function() {
            var exportType = $$('input:checked[type=radio][name="export-type"]')[0].value;

            var pedOptionsTable = $("pedOptions");
            var pedDisorderOptions = $$('[name="ped-disorders-options"]');
            var jsonOptionsTable = $("jsonOptions");
            var imageOptionsTable = $("imageOptions");

            if (exportType == "ped" || exportType == "BOADICEA") {
                pedOptionsTable.show();
                var idgenerator = $$('input[type=radio][name="ped-options"]')[2];
                // disable using names as IDs - not necessary for BOADICEA which supports a dedicated column for the name
                if (exportType == "BOADICEA") {
                    if (idgenerator.checked) {
                        $$('input[type=radio][name="ped-options"]')[0].checked = true;
                    }
                    idgenerator.up().hide();
                    pedDisorderOptions.each( function(item) {item.up('tr').hide();});
                } else {
                    idgenerator.up().show();
                    pedDisorderOptions.each( function(item) {item.up('tr').show();});
                }
                jsonOptionsTable.hide();
                imageOptionsTable.hide();
            } else {
                pedOptionsTable.hide();
                pedDisorderOptions.each( function(item) {item.up('tr').hide();});
                if (exportType == "simpleJSON") {
                    jsonOptionsTable.show();
                    imageOptionsTable.hide();
                } else {
                    jsonOptionsTable.hide();
                    imageOptionsTable.show();
                }
            }
        },

        _onExportStarted: function() {
            this.hide();

            var patientDocument = XWiki.currentDocument.page + "_pedigree";

            var exportType = $$('input:checked[type=radio][name="export-type"]')[0].value;
            //console.log("Import type: " + exportType);

            if (exportType == "image") {
                var imageType = $$('input:checked[type=radio][name="image-options"]')[0].value;

                var _bbox = $('canvas').down().getBBox();
                //set white background
                var svgEl = $$("#canvas svg")[0];
                var background = $$('.panning-background')[0];
                svgEl.insertBefore(new Element('rect', {"id": "white-bbox-background",
                                                        "width": _bbox.width,
                                                        "height": _bbox.height,
                                                        "x": _bbox.x,
                                                        "y": _bbox.y,
                                                        "fill": "white"}),
                                   svgEl.firstChild
                );

                var svg = editor.getWorkspace().getSVGCopy();
                var exportString = svg.getSVGText();
                $('white-bbox-background').remove();

                if (imageType == "png") {
                    // generate PNG image on the back end
                    var pedigreeImageExportServiceURL = editor.getExternalEndpoint().getPedigreeImageExportServiceURL();
                    new Ajax.Request(pedigreeImageExportServiceURL, {
                        method: 'POST',
                        onSuccess: function(response) {
                            if (response.responseJSON && response.responseJSON.url) {
                                $('body').insert('<iframe width="0" height="0" src="' + response.responseJSON.url + '"></iframe>');
                            }
                        },
                        onFailure : function(response) {
                            var errorMessage = '';
                            if (response.statusText == '' /* No response */ || response.status == 12031 /* In IE */) {
                                  errorMessage = 'Server not responding';
                              } else if (response.getHeader('Content-Type').match(/^\s*text\/plain/)) {
                                  // Regard the body of plain text responses as custom status messages.
                                  errorMessage = response.responseText;
                              } else if (response.responseJSON && response.responseJSON.error) {
                                  errorMessage = response.responseJSON.error;
                            }
                            var content = new Element('div', {'class' : 'box errormessage'});
                            content.insert(new Element('p').update("Pedigree image export failed: " + errorMessage));
                            var d = new PhenoTips.widgets.ModalPopup(content, '', {'titleColor' : '#000'});
                            d.show();
                        },
                        parameters: {"image": exportString}
                    });
                } else {
                     var fileName = patientDocument + ".svg";
                }

            } else if (exportType == "simpleJSON") {
                var privacySetting = $$('input:checked[type=radio][name="export-options"]')[0].value;
                var exportString = PedigreeExport.exportAsSimpleJSON(editor.getGraph().DG, privacySetting);
                var fileName = patientDocument + ".json";
                var mimeType = "application/json";
            } else {
                var idGenerationSetting = $$('input:checked[type=radio][name="ped-options"]')[0].value;
                if (exportType == "ped") {
                    var selectedDisorders = $$('input:checked[name="ped-disorders-options"]');
                    if (selectedDisorders.indexOf("all") > -1) {
                        var exportString = PedigreeExport.exportAsPED(editor.getGraph().DG, idGenerationSetting);
                    } else {
                        var exportString = PedigreeExport.exportAsPED(editor.getGraph().DG, idGenerationSetting, selectedDisorders);
                    }
                    var fileName = patientDocument + ".ped";
                } else if (exportType == "BOADICEA") {
                    var exportString = PedigreeExport.exportAsBOADICEA(editor.getGraph(), idGenerationSetting);
                    var fileName = patientDocument + ".txt";
                }
                var mimeType = "text/plain";
            }

            console.log("Export data: >>" + exportString + "<<");
            if (exportString != "") {
                if (exportType != "image") {
                    FileSaver.saveTextFile(exportString, fileName);
                } else if (exportType == "image" && imageType == "svg") {
                    FileSaver.saveSVGFile(exportString, fileName);
                }
            }
        },

        /**
         * Displays the template selector
         *
         * @method show
         */
        show: function() {
            if ($$('input[name="ped-disorders-options"]').length > 0)
                $$('[name="ped-disorders-options"]').each( function(item) {item.up('tr').remove();});
            var disorders = editor.getDisorderLegend().getAllNames();
            var hasDisorders = false;
            var disordersLength = 0;
            for (var key in disorders) {
                if (hasOwnProperty.call(disorders, key)) {
                    hasDisorders = true;
                    disordersLength++;
                }
            }
            if (hasDisorders && disordersLength > 1) {
                var configListElementPED = this.dialog.content.select('#pedOptions')[0];
                var labelDisorderOptions = new Element('label', {'class': 'export-config-header ped-disorders-options', 'name' : 'ped-disorders-options', 'style' : 'margin-top: 0.5em;'}).insert("Which disorders should be reflected in the affected column in PED file? ");
                configListElementPED.insert(labelDisorderOptions.wrap('td').wrap('tr'));
                configListElementPED.insert(this._addConfigOption(true,  "ped-disorders-options", "export-subconfig-label", "All", "all", "checkbox"));
                for (var disorder in disorders) {
                    if (disorder == "affected") {
                        configListElementPED.insert(this._addConfigOption(false,  "ped-disorders-options", "export-subconfig-label", "Unspecified disorder", "affected", "checkbox"));
                    } else {
                        configListElementPED.insert(this._addConfigOption(false,  "ped-disorders-options", "export-subconfig-label", disorders[disorder], disorder, "checkbox"));
                    }
                }
                configListElementPED.on('click', 'input[type=checkbox]', function(event, element) {
                    if (element.value == "all" && element.checked) {
                        //check others
                        $$('input[name="ped-disorders-options"]').each( function(item) {item.checked = true;});
                    } else if (element.value != "all") {
                        // uncheck all
                        $$('input[name="ped-disorders-options"]')[0].checked = false;
                    }
                });
            }

            this.dialog.show();
        },

        /**
         * Removes the the template selector
         *
         * @method hide
         */
        hide: function() {
            this.dialog.closeDialog();
        },

        _addConfigOption: function (checked, name, cssClass, labelText, value, type) {
            var optionWrapper = new Element('tr');
            var itype = type ? type : "radio";
            var input = new Element('input', {"type" : itype, "value": value, "name": name });
            if (checked) {
              input.checked = true;
            }
            var label = new Element('label', {'class': cssClass}).insert(input).insert(labelText);
            optionWrapper.insert(label.wrap('td'));
            return optionWrapper;
        }
    });
    return ExportSelector;
});
<commit_msg>PT-2230: Allow exporting pedigree as an image from within pedigree editor Bugfix: Network issues were silently ignored instead of showing a warning message<commit_after>/**
 * The UI Element for exporting pedigrees
 *
 * @class ExportSelector
 */
define([
        "pedigree/filesaver/FileSaver",
        "pedigree/model/export"
    ], function(
        FileSaver,
        PedigreeExport
    ){
    var ExportSelector = Class.create( {

        initialize: function() {
            var _this = this;

            var mainDiv = new Element('div', {'class': 'export-selector'});

            var _addTypeOption = function (checked, labelText, value) {
                var optionWrapper = new Element('tr');
                var input = new Element('input', {"type" : "radio", "value": value, "name": "export-type"});
                input.observe('click', _this.disableEnableOptions );
                if (checked) {
                  input.checked = true;
                }
                var label = new Element('label', {'class': 'import-type-label'}).insert(input).insert(labelText);
                optionWrapper.insert(label.wrap('td'));
                return optionWrapper;
              };
            var typeListElement = new Element('table');
            typeListElement.insert(_addTypeOption(true,  "PED", "ped"));
            typeListElement.insert(_addTypeOption(false, "BOADICEA", "BOADICEA"));
            typeListElement.insert(_addTypeOption(false, "Simple JSON", "simpleJSON"));
            typeListElement.insert(_addTypeOption(false, "Image", "image"));
            //TODO: typeListElement.insert(_addTypeOption(false, "Phenotips Pedigree JSON", "phenotipsJSON"));

            var fileDownload = new Element('a', {"id": 'downloadLink', "style": 'display:none'});
            mainDiv.insert(fileDownload);

            var promptType = new Element('div', {'class': 'import-section'}).update("Data format:");
            var dataSection2 = new Element('div', {'class': 'import-block'});
            dataSection2.insert(promptType).insert(typeListElement);
            mainDiv.insert(dataSection2);

            var configListElementJSON = new Element('table', {"id": "jsonOptions", "style": 'display:none'});
            configListElementJSON.insert(this._addConfigOption(true,  "export-options", "import-config-label", "All data", "all"));
            configListElementJSON.insert(this._addConfigOption(false, "export-options", "import-config-label", "Remove personal information (name and age)", "nopersonal"));
            configListElementJSON.insert(this._addConfigOption(false, "export-options", "import-config-label", "Remove personal information and free-form comments", "minimal"));

            var configListElementPED = new Element('table', {"id": "pedOptions"});
            var label = new Element('label', {'class': 'export-config-header'}).insert("How should person IDs be assigned in the generated file?");
            configListElementPED.insert(label.wrap('td').wrap('tr'));
            configListElementPED.insert(this._addConfigOption(true,  "ped-options", "export-subconfig-label", "Using External IDs (when available)", "external"));
            configListElementPED.insert(this._addConfigOption(false, "ped-options", "export-subconfig-label", "Generate new numeric IDs", "newid"));
            configListElementPED.insert(this._addConfigOption(false, "ped-options", "export-subconfig-label", "Using Names (when available)", "name"));

            var configListElementImage = new Element('table', {"id": "imageOptions", "style": 'display:none'});
            var label = new Element('label', {'class': 'export-config-header'}).insert("Select type of generated pedigree image");
            configListElementImage.insert(label.wrap('td').wrap('tr'));
            configListElementImage.insert(this._addConfigOption(true,  "image-options", "export-subconfig-label", "Raster image (PNG)", "png"));
            configListElementImage.insert(this._addConfigOption(false, "image-options", "export-subconfig-label", "Scalable image (SVG)", "svg"));

            var promptConfig = new Element('div', {'class': 'import-section'}).update("Options:");
            var dataSection3 = new Element('div', {'class': 'import-block'});
            dataSection3.insert(promptConfig).insert(configListElementJSON).insert(configListElementPED).insert(configListElementImage);
            mainDiv.insert(dataSection3);

            var buttons = new Element('div', {'class' : 'buttons import-block-bottom'});
            buttons.insert(new Element('input', {type: 'button', name : 'export', 'value': 'Export', 'class' : 'button', 'id': 'export_button'}).wrap('span', {'class' : 'buttonwrapper'}));
            buttons.insert(new Element('input', {type: 'button', name : 'cancel', 'value': 'Cancel', 'class' : 'button secondary'}).wrap('span', {'class' : 'buttonwrapper'}));
            mainDiv.insert(buttons);

            var cancelButton = buttons.down('input[name="cancel"]');
            cancelButton.observe('click', function(event) {
                _this.hide();
            })
            var exportButton = buttons.down('input[name="export"]');
            exportButton.observe('click', function(event) {
                _this._onExportStarted();
            })

            var closeShortcut = ['Esc'];
            this.dialog = new PhenoTips.widgets.ModalPopup(mainDiv, {close: {method : this.hide.bind(this), keys : closeShortcut}}, {extraClassName: "pedigree-import-chooser", title: "Pedigree export", displayCloseButton: true});
        },

        /*
         * Disables unapplicable options on input type selection
         */
        disableEnableOptions: function() {
            var exportType = $$('input:checked[type=radio][name="export-type"]')[0].value;

            var pedOptionsTable = $("pedOptions");
            var pedDisorderOptions = $$('[name="ped-disorders-options"]');
            var jsonOptionsTable = $("jsonOptions");
            var imageOptionsTable = $("imageOptions");

            if (exportType == "ped" || exportType == "BOADICEA") {
                pedOptionsTable.show();
                var idgenerator = $$('input[type=radio][name="ped-options"]')[2];
                // disable using names as IDs - not necessary for BOADICEA which supports a dedicated column for the name
                if (exportType == "BOADICEA") {
                    if (idgenerator.checked) {
                        $$('input[type=radio][name="ped-options"]')[0].checked = true;
                    }
                    idgenerator.up().hide();
                    pedDisorderOptions.each( function(item) {item.up('tr').hide();});
                } else {
                    idgenerator.up().show();
                    pedDisorderOptions.each( function(item) {item.up('tr').show();});
                }
                jsonOptionsTable.hide();
                imageOptionsTable.hide();
            } else {
                pedOptionsTable.hide();
                pedDisorderOptions.each( function(item) {item.up('tr').hide();});
                if (exportType == "simpleJSON") {
                    jsonOptionsTable.show();
                    imageOptionsTable.hide();
                } else {
                    jsonOptionsTable.hide();
                    imageOptionsTable.show();
                }
            }
        },

        _onExportStarted: function() {
            this.hide();

            var patientDocument = XWiki.currentDocument.page + "_pedigree";

            var exportType = $$('input:checked[type=radio][name="export-type"]')[0].value;
            //console.log("Import type: " + exportType);

            if (exportType == "image") {
                var imageType = $$('input:checked[type=radio][name="image-options"]')[0].value;

                var _bbox = $('canvas').down().getBBox();
                //set white background
                var svgEl = $$("#canvas svg")[0];
                var background = $$('.panning-background')[0];
                svgEl.insertBefore(new Element('rect', {"id": "white-bbox-background",
                                                        "width": _bbox.width,
                                                        "height": _bbox.height,
                                                        "x": _bbox.x,
                                                        "y": _bbox.y,
                                                        "fill": "white"}),
                                   svgEl.firstChild
                );

                var svg = editor.getWorkspace().getSVGCopy();
                var exportString = svg.getSVGText();
                $('white-bbox-background').remove();

                if (imageType == "png") {
                    // generate PNG image on the back end
                    var pedigreeImageExportServiceURL = editor.getExternalEndpoint().getPedigreeImageExportServiceURL();
                    new Ajax.Request(pedigreeImageExportServiceURL, {
                        method: 'POST',
                        onSuccess: function(response) {
                            if (response.responseJSON && response.responseJSON.url) {
                                $('body').insert('<iframe width="0" height="0" src="' + response.responseJSON.url + '"></iframe>');
                            }
                        },
                        onFailure : function(response) {
                            var errorMessage = '';
                            if (response.statusText == '' /* No response */ || response.status == 12031 /* In IE */) {
                                  errorMessage = 'Server not responding';
                              } else if (response.getHeader('Content-Type').match(/^\s*text\/plain/)) {
                                  // Regard the body of plain text responses as custom status messages.
                                  errorMessage = response.responseText;
                              } else if (response.responseJSON && response.responseJSON.error) {
                                  errorMessage = response.responseJSON.error;
                            }
                            var content = new Element('div', {'class' : 'box errormessage'});
                            content.insert(new Element('p').update("Pedigree image export failed: " + errorMessage));
                            var d = new PhenoTips.widgets.ModalPopup(content, '', {'titleColor' : '#000'});
                            d.show();
                        },
                        on1223 : function(response) {
                            response.request.options.onSuccess(response);
                        },
                        on0 : function(response) {
                            response.request.options.onFailure(response);
                        },
                        parameters: {"image": exportString}
                    });
                } else {
                     var fileName = patientDocument + ".svg";
                }

            } else if (exportType == "simpleJSON") {
                var privacySetting = $$('input:checked[type=radio][name="export-options"]')[0].value;
                var exportString = PedigreeExport.exportAsSimpleJSON(editor.getGraph().DG, privacySetting);
                var fileName = patientDocument + ".json";
                var mimeType = "application/json";
            } else {
                var idGenerationSetting = $$('input:checked[type=radio][name="ped-options"]')[0].value;
                if (exportType == "ped") {
                    var selectedDisorders = $$('input:checked[name="ped-disorders-options"]');
                    if (selectedDisorders.indexOf("all") > -1) {
                        var exportString = PedigreeExport.exportAsPED(editor.getGraph().DG, idGenerationSetting);
                    } else {
                        var exportString = PedigreeExport.exportAsPED(editor.getGraph().DG, idGenerationSetting, selectedDisorders);
                    }
                    var fileName = patientDocument + ".ped";
                } else if (exportType == "BOADICEA") {
                    var exportString = PedigreeExport.exportAsBOADICEA(editor.getGraph(), idGenerationSetting);
                    var fileName = patientDocument + ".txt";
                }
                var mimeType = "text/plain";
            }

            console.log("Export data: >>" + exportString + "<<");
            if (exportString != "") {
                if (exportType != "image") {
                    FileSaver.saveTextFile(exportString, fileName);
                } else if (exportType == "image" && imageType == "svg") {
                    FileSaver.saveSVGFile(exportString, fileName);
                }
            }
        },

        /**
         * Displays the template selector
         *
         * @method show
         */
        show: function() {
            if ($$('input[name="ped-disorders-options"]').length > 0)
                $$('[name="ped-disorders-options"]').each( function(item) {item.up('tr').remove();});
            var disorders = editor.getDisorderLegend().getAllNames();
            var hasDisorders = false;
            var disordersLength = 0;
            for (var key in disorders) {
                if (hasOwnProperty.call(disorders, key)) {
                    hasDisorders = true;
                    disordersLength++;
                }
            }
            if (hasDisorders && disordersLength > 1) {
                var configListElementPED = this.dialog.content.select('#pedOptions')[0];
                var labelDisorderOptions = new Element('label', {'class': 'export-config-header ped-disorders-options', 'name' : 'ped-disorders-options', 'style' : 'margin-top: 0.5em;'}).insert("Which disorders should be reflected in the affected column in PED file? ");
                configListElementPED.insert(labelDisorderOptions.wrap('td').wrap('tr'));
                configListElementPED.insert(this._addConfigOption(true,  "ped-disorders-options", "export-subconfig-label", "All", "all", "checkbox"));
                for (var disorder in disorders) {
                    if (disorder == "affected") {
                        configListElementPED.insert(this._addConfigOption(false,  "ped-disorders-options", "export-subconfig-label", "Unspecified disorder", "affected", "checkbox"));
                    } else {
                        configListElementPED.insert(this._addConfigOption(false,  "ped-disorders-options", "export-subconfig-label", disorders[disorder], disorder, "checkbox"));
                    }
                }
                configListElementPED.on('click', 'input[type=checkbox]', function(event, element) {
                    if (element.value == "all" && element.checked) {
                        //check others
                        $$('input[name="ped-disorders-options"]').each( function(item) {item.checked = true;});
                    } else if (element.value != "all") {
                        // uncheck all
                        $$('input[name="ped-disorders-options"]')[0].checked = false;
                    }
                });
            }

            this.dialog.show();
        },

        /**
         * Removes the the template selector
         *
         * @method hide
         */
        hide: function() {
            this.dialog.closeDialog();
        },

        _addConfigOption: function (checked, name, cssClass, labelText, value, type) {
            var optionWrapper = new Element('tr');
            var itype = type ? type : "radio";
            var input = new Element('input', {"type" : itype, "value": value, "name": name });
            if (checked) {
              input.checked = true;
            }
            var label = new Element('label', {'class': cssClass}).insert(input).insert(labelText);
            optionWrapper.insert(label.wrap('td'));
            return optionWrapper;
        }
    });
    return ExportSelector;
});
<|endoftext|>


<commit_before>import React from 'react'
import { storiesOf } from '@kadira/storybook'
import {Row} from '../Layout'
import {CelebrateIcon, AlertIcon, CloseIcon, WordMark, LogoMark} from './index'

storiesOf('icons', module)
  .add('CelebrateIcon', () => (
    <Row p='0'>
      <CelebrateIcon size={100} />
      <CelebrateIcon size={300} />
    </Row>
  ))
  .add('AlertIcon', () => (
    <Row p='0'>
      <AlertIcon size={100} />
      <AlertIcon size={300} />
    </Row>
  ))
  .add('CloseIcon', () => (
    <Row p='0'>
      <CloseIcon size={100} color='blue' />
      <CloseIcon size={300} color='#ccc'/>
    </Row>
  ))
  .add('Wordmark', () => (
    <Row p='0'>
      <WordMark size={100} color='blue' />
      <WordMark size={300} color='#ccc'/>
      <WordMark />
    </Row>
  ))
  .add('LogoMark', () => (
    <Row p='0'>
      <LogoMark size={100}/>
      <LogoMark size={300}/>
      <LogoMark />
    </Row>
  ))
<commit_msg>create dev branch<commit_after>import React from 'react'
import { storiesOf } from '@kadira/storybook'
import {Row} from '../Layout'
import {CelebrateIcon, AlertIcon, CloseIcon, WordMark, LogoMark} from './index'

storiesOf('icons', module)
  .add('CelebrateIcon', () => (
    <Row p='0'>
      <CelebrateIcon size={100} />
      <CelebrateIcon size={300} />
    </Row>
  ))
  .add('AlertIcon', () => (
    <Row p='0'>
      <AlertIcon size={100} />
      <AlertIcon size={300} />
    </Row>
  ))
  .add('CloseIcon', () => (
    <Row p='0'>
      <CloseIcon size={100} color='blue' />
      <CloseIcon size={300} color='#ccc'/>
    </Row>
  ))
  .add('Wordmark', () => (
    <Row p='0'>
      <WordMark size={100} color='blue' />
      <WordMark size={300} color='#ccc'/>
      <WordMark />
    </Row>
  ))
  .add('LogoMark', () => (
    <Row p='0'>
      <LogoMark size={100}/>
      <LogoMark size={300}/>
      <LogoMark />
    </Row>
  ))
<|endoftext|>


<commit_before>// Never set the rotation of a button
// All units, such as throw, are designed to go in the negative Z
// Add it to a parent/pivot, and rotate that.

var PushButton = function(interactablePlane){
  this.plane = interactablePlane;
  this.plane.returnSpring = this.plane.mass;

  this.longThrow  = -0.05;
  this.shortThrow = -0.03;

  this.pressed = false;
  this.canChangeState = true;
  this.plane.movementConstraints.z = this.releasedConstraint.bind(this);

  this.on('press', function(){
    this.pressed = true;

    this.plane.movementConstraints.z = this.pressedConstraint.bind(this);
    this.plane.mesh.material.color.setHex(0xccccff);

  }.bind(this));

  this.on('release', function(){
    this.pressed = false;

    this.plane.movementConstraints.z = this.releasedConstraint.bind(this);
    this.plane.mesh.material.color.setHex(0xeeeeee);

  }.bind(this));

};

// todo - make these oriented in the direction plane normal
// returns the correct position
PushButton.prototype.releasedConstraint = function(z){
  var origZ = this.plane.originalPosition.z;

  if (z > origZ) {
    this.canChangeState = true;
    return origZ;
  }

  if (z < origZ + this.longThrow){
    if (!this.pressed && this.canChangeState){
      this.canChangeState = false;
      this.emit('press');
    }
    return origZ + this.longThrow;
  }

  return z;

};

PushButton.prototype.pressedConstraint = function(z){
  var origZ = this.plane.originalPosition.z;

  if (z > origZ + this.shortThrow) {
    this.canRelease = true;
    return origZ + this.shortThrow;
  }

  if (z < origZ + this.longThrow){
    if (this.pressed && this.canRelease) {
      this.canRelease = false;
      this.emit('release');
    }
    return origZ + this.longThrow;
  }

  return z;

};

Leap._.extend(PushButton.prototype, Leap.EventEmitter.prototype);
<commit_msg>Button sets default opts for interactablePlane<commit_after>// Never set the rotation of a button
// All units, such as throw, are designed to go in the negative Z
// Add it to a parent/pivot, and rotate that.
// alternatively, we could have it so that constraints themselves are transformed by mesh.matrix
// are there any potential cases where such a thing would be bad?
// - if the base shape had to be rotated to appear correct
// it would be nice to not have to wrap a button, just to rotate it.

var PushButton = function(interactablePlane){
  this.plane = interactablePlane;
  this.plane.returnSpring = this.plane.mass;
  this.plane.moveX = false;
  this.plane.moveY = false;
  this.plane.moveZ = true;

  this.longThrow  = -0.05;
  this.shortThrow = -0.03;

  this.pressed = false;
  this.canChangeState = true;
  this.plane.movementConstraints.z = this.releasedConstraint.bind(this);

  this.on('press', function(){
    this.pressed = true;

    this.plane.movementConstraints.z = this.pressedConstraint.bind(this);
    this.plane.mesh.material.color.setHex(0xccccff);

  }.bind(this));

  this.on('release', function(){
    this.pressed = false;

    this.plane.movementConstraints.z = this.releasedConstraint.bind(this);
    this.plane.mesh.material.color.setHex(0xeeeeee);

  }.bind(this));

};

// todo - make these oriented in the direction plane normal
// returns the correct position
PushButton.prototype.releasedConstraint = function(z){
  var origZ = this.plane.originalPosition.z;

  if (z > origZ) {
    this.canChangeState = true;
    return origZ;
  }

  if (z < origZ + this.longThrow){
    if (!this.pressed && this.canChangeState){
      this.canChangeState = false;
      this.emit('press');
    }
    return origZ + this.longThrow;
  }

  return z;

};

PushButton.prototype.pressedConstraint = function(z){
  var origZ = this.plane.originalPosition.z;

  if (z > origZ + this.shortThrow) {
    this.canRelease = true;
    return origZ + this.shortThrow;
  }

  if (z < origZ + this.longThrow){
    if (this.pressed && this.canRelease) {
      this.canRelease = false;
      this.emit('release');
    }
    return origZ + this.longThrow;
  }

  return z;

};

Leap._.extend(PushButton.prototype, Leap.EventEmitter.prototype);
<|endoftext|>


<commit_before> /*globals phantom*/

 /**
  * Preamble's phantom-runner script.
  * Requires phantomjs v2.x.
  */

(function(phantom){
    'use strict';

    var system = require('system');

    /**
     * Wait until the test condition is true or a timeout occurs. Useful for waiting
     * on a server response or for a ui change (fadeIn, etc.) to occur.
     *
     * @param testFx javascript condition that evaluates to a boolean,
     * it can be passed in as a string (e.g.: '1 == 1' or '$('#bar').is(':visible')' or
     * as a callback function.
     * @param onReady what to do when testFx condition is fulfilled,
     * it can be passed in as a string (e.g.: '1 == 1' or '$('#bar').is(':visible')' or
     * as a callback function.
     * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
     */
    function waitFor(testFx, onReady, timeOutMillis) {
        var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 30001, //< Default Max Timout is 30s
            start = new Date().getTime(),
            condition = false,
            interval = setInterval(function() {
                if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
                    // If not time-out yet and condition not yet fulfilled
                    condition = (typeof(testFx) === 'string' ? eval(testFx) : testFx()); //< defensive code
                } else {
                    if(!condition) {
                        // If condition still not fulfilled (timeout but condition is 'false')
                        console.log('\'waitFor()\' timeout');
                        phantom.exit(1);
                    } else {
                        // Condition fulfilled (timeout and/or condition is 'true')
                        console.log('\'waitFor()\' finished in ' + (new Date().getTime() - start) + 'ms.');
                        typeof(onReady) === 'string' ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                        clearInterval(interval); //< Stop this interval
                    }
                }
            }, 100); //< repeat check every 100ms
    }

    if (system.args.length === 0 || system.args.length > 2) {
        console.log('Usage: phantom-runner.js URL');
        phantom.exit(1);
    }

    var page = require('webpage').create();

    // Route 'console.log()' calls from within the Page context to the main Phantom context (i.e. current 'this')
    page.onConsoleMessage = function(msg) {
        console.log(msg);
    };

    page.open(system.args[1], function(status){
        if (status !== 'success') {
            console.log('Unable to access network');
            phantom.exit(1);
        } else {
            waitFor(function(){
                return page.evaluate(function(){
                    var el = document.getElementById('preamble-results-summary-passed') ||
                        document.getElementById('preamble-results-summary-failed');
                    if (el) {
                        return true;
                    }
                    return false;
                });
            }, function(){
                var elFailed;
                page.evaluate(function(){
                    var elPassed = document.getElementById('preamble-results-summary-passed');
                    if(elPassed){
                        console.log(elPassed.innerText);
                    }
                    elFailed = document.getElementById('preamble-results-summary-failed');
                    if(elFailed){
                        console.log(elFailed.innerText);
                    }
                });
                phantom.exit(elFailed ? 1 : 0);
            });
        }
    });
}(phantom));
<commit_msg>Now showing coverage and time in PhantomJS output.<commit_after> /*globals phantom*/

 /**
  * Preamble's phantom-runner script.
  * Requires phantomjs v2.x.
  */

(function(phantom){
    'use strict';

    var system = require('system');

    /**
     * Wait until the test condition is true or a timeout occurs. Useful for waiting
     * on a server response or for a ui change (fadeIn, etc.) to occur.
     *
     * @param testFx javascript condition that evaluates to a boolean,
     * it can be passed in as a string (e.g.: '1 == 1' or '$('#bar').is(':visible')' or
     * as a callback function.
     * @param onReady what to do when testFx condition is fulfilled,
     * it can be passed in as a string (e.g.: '1 == 1' or '$('#bar').is(':visible')' or
     * as a callback function.
     * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
     */
    function waitFor(testFx, onReady, timeOutMillis) {
        var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 30001, //< Default Max Timout is 30s
            start = new Date().getTime(),
            condition = false,
            interval = setInterval(function() {
                if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
                    // If not time-out yet and condition not yet fulfilled
                    condition = (typeof(testFx) === 'string' ? eval(testFx) : testFx()); //< defensive code
                } else {
                    if(!condition) {
                        // If condition still not fulfilled (timeout but condition is 'false')
                        console.log('\'waitFor()\' timeout');
                        phantom.exit(1);
                    } else {
                        // Condition fulfilled (timeout and/or condition is 'true')
                        console.log('\'waitFor()\' finished in ' + (new Date().getTime() - start) + 'ms.');
                        typeof(onReady) === 'string' ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                        clearInterval(interval); //< Stop this interval
                    }
                }
            }, 100); //< repeat check every 100ms
    }

    if (system.args.length === 0 || system.args.length > 2) {
        console.log('Usage: phantom-runner.js URL');
        phantom.exit(1);
    }

    var page = require('webpage').create();

    // Route 'console.log()' calls from within the Page context to the main Phantom context (i.e. current 'this')
    page.onConsoleMessage = function(msg) {
        console.log(msg);
    };

    page.open(system.args[1], function(status){
        var timer;
        if (status !== 'success') {
            console.log('Unable to access network');
            phantom.exit(1);
        } else {
            page.evaluate(function(){
                timer = setInterval(function(){
                    var elName = document.getElementById('name'),
                        elVersion = document.getElementById('version');
                    if(elName && elVersion){
                        console.log(elName.innerText + ' - ' + elVersion.innerText);
                        clearInterval(timer);
                    }
                }, 1);
            });
            waitFor(function(){
                return page.evaluate(function(){
                    var el = document.getElementById('preamble-results-summary-passed') ||
                        document.getElementById('preamble-results-summary-failed');
                    if (el) {
                        return true;
                    }
                    return false;
                });
            }, function(){
                var elFailed;
                page.evaluate(function(){
                    var elPassed = document.getElementById('preamble-results-summary-passed'),
                        elCoverageText = document.getElementById('coverage').innerText,
                        elTimeText = document.getElementById('time').innerText;
                    console.log(elCoverageText.substr(0, elCoverageText.indexOf('Hide')) + '.');
                    console.log(elTimeText + '.');
                    if(elPassed){
                        console.log(elPassed.innerText);
                    }
                    elFailed = document.getElementById('preamble-results-summary-failed');
                    if(elFailed){
                        console.log(elFailed.innerText);
                    }
                });
                phantom.exit(elFailed ? 1 : 0);
            });
        }
    });
}(phantom));
<|endoftext|>


<commit_before>/*
*
* jRails ajax extras
* version 0.1
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$().ajaxSend(function(a, xhr, s){ //Set request headers globally
		xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
	});
})(jQuery);

/*
*
* jRails form extras
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

// reset a form
(function($) {
	$.fn.reset = function() {
		return this.each(function() {
			// guard against an input with the name of 'reset'
			// note that IE reports the reset function as an 'object'
			if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
				this.reset();
		});
	};
})(jQuery);

/*
*
* jRails form observer plugin
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.extend({ // Translate field to event
		fieldEvent: function(el, obs) {
			var field = el[0] || el, e = 'change';
			if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
			else if (obs && field.type == 'text' || field.type == 'textarea') e = 'keyup';
			return e;
		}
	});
	$.fn.extend({ // Delayed observer for fields and forms
		delayedObserver: function(delay, callback){
			var el = $(this);
			if (typeof window.delayedObserverStack == 'undefined') window.delayedObserverStack = [];
			if (typeof window.delayedObserverCallback == 'undefined') {
				window.delayedObserverCallback = function(stackPos) {
					observed = window.delayedObserverStack[stackPos];
					if (observed.timer) clearTimeout(observed.timer);
					observed.timer = setTimeout(function(){
						observed.timer = null;
						observed.callback(observed.obj, observed.obj.formVal());
					}, observed.delay * 1000);
					observed.oldVal = observed.obj.formVal();
				}
			}
			window.delayedObserverStack.push({
				obj: el, timer: null, delay: delay,
				oldVal: el.formVal(), callback: callback
			});
			var stackPos = window.delayedObserverStack.length-1;
			if (el[0].tagName == 'FORM') {
				$(':input', el).each(function(){
					var field = $(this);
					field.bind($.fieldEvent(field, delay), function(){
						observed = window.delayedObserverStack[stackPos];
						if (observed.obj.formVal() == observed.obj.oldVal) return;
						else window.delayedObserverCallback(stackPos);
					});
				});
			} else {
				el.bind($.fieldEvent(el, delay), function(){
					observed = window.delayedObserverStack[stackPos];
					if (observed.obj.formVal() == observed.obj.oldVal) return;
					else window.delayedObserverCallback(stackPos);
				});
			};
		},
		formVal: function() { // Gets form values
			var el = this[0];
			if(el.tagName == 'FORM') return this.serialize();
			if(el.type == 'checkbox' || self.type == 'radio') return this.filter('input:checked').val() || '';
			else return this.val();
		}
	});
})(jQuery);

/*
*
* jRails visual effects stubs
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.fn.extend({
		visualEffect : function(o) {
			e = o.replace(/\_(.)/g, function(m, l){return l.toUpperCase()});
			return eval('$(this).'+e+'()');
		},
		appear : function(speed, callback) {
			return this.fadeIn(speed, callback);
		},
		blindDown : function(speed, callback) {
			return this.show('blind', { direction: 'vertical' }, speed, callback);
		},
		blindUp : function(speed, callback) {
			return this.hide('blind', { direction: 'vertical' }, speed, callback);
		},
		blindRight : function(speed, callback) {
			return this.show('blind', { direction: 'horizontal' }, speed, callback);
		},
		blindLeft : function(speed, callback) {
			this.hide('blind', { direction: 'horizontal' }, speed, callback);
			return this;
		},
		dropOut : function(speed, callback) {
			return this.hide('drop', {direction: 'down' }, speed, callback);
		},
		dropIn : function(speed, callback) {
			return this.show('drop', { direction: 'up' }, speed, callback);
		},
		fade : function(speed, callback) {
			return this.fadeOut(speed, callback);
		},
		fadeToggle = function(speed, callback) {
			return this.animate({opacity: 'toggle'}, speed, callback);
		},
		fold : function(speed, callback) {
			return this.hide('fold', {}, speed, callback);
		},
		foldOut : function(speed, callback) {
			return this.show('fold', {}, speed, callback);
		},
		grow : function(speed, callback) {
			return this.show('scale', {}, speed, callback);
		},
		highlight : function(speed, callback) {
			return this.show('highlight', {}, speed, callback);
		},
		puff : function(speed, callback) {
			return this.hide('puff', {}, speed, callback);
		},
		pulsate : function(speed, callback) {
			return this.show('pulsate', {}, speed, callback);
		},
		shake : function(speed, callback) {
			return this.show('shake', {}, speed, callback);
		},
		shrink : function(speed, callback) {
			return this.hide('scale', {}, speed, callback);
		},
		squish : function(speed, callback) {
			return this.hide('scale', { origin: ['top', 'left'] }, speed, callback);
		},
		slideUp : function(speed, callback) {
			return this.hide('slide', { direction: 'up'}, speed, callback);
		},
		slideDown : function(speed, callback) {
			return this.show('slide', { direction: 'up'}, speed, callback);
		},
		switchOff : function(speed, callback) {
			return this.hide('clip', {}, speed, callback);
		},
		switchOn : function(speed, callback) {
			return this.show('clip', {}, speed, callback);
		}
	});
})(jQuery);
<commit_msg>fix fadeToggle<commit_after>/*
*
* jRails ajax extras
* version 0.1
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$().ajaxSend(function(a, xhr, s){ //Set request headers globally
		xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
	});
})(jQuery);

/*
*
* jRails form extras
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

// reset a form
(function($) {
	$.fn.reset = function() {
		return this.each(function() {
			// guard against an input with the name of 'reset'
			// note that IE reports the reset function as an 'object'
			if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
				this.reset();
		});
	};
})(jQuery);

/*
*
* jRails form observer plugin
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.extend({ // Translate field to event
		fieldEvent: function(el, obs) {
			var field = el[0] || el, e = 'change';
			if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
			else if (obs && field.type == 'text' || field.type == 'textarea') e = 'keyup';
			return e;
		}
	});
	$.fn.extend({ // Delayed observer for fields and forms
		delayedObserver: function(delay, callback){
			var el = $(this);
			if (typeof window.delayedObserverStack == 'undefined') window.delayedObserverStack = [];
			if (typeof window.delayedObserverCallback == 'undefined') {
				window.delayedObserverCallback = function(stackPos) {
					observed = window.delayedObserverStack[stackPos];
					if (observed.timer) clearTimeout(observed.timer);
					observed.timer = setTimeout(function(){
						observed.timer = null;
						observed.callback(observed.obj, observed.obj.formVal());
					}, observed.delay * 1000);
					observed.oldVal = observed.obj.formVal();
				}
			}
			window.delayedObserverStack.push({
				obj: el, timer: null, delay: delay,
				oldVal: el.formVal(), callback: callback
			});
			var stackPos = window.delayedObserverStack.length-1;
			if (el[0].tagName == 'FORM') {
				$(':input', el).each(function(){
					var field = $(this);
					field.bind($.fieldEvent(field, delay), function(){
						observed = window.delayedObserverStack[stackPos];
						if (observed.obj.formVal() == observed.obj.oldVal) return;
						else window.delayedObserverCallback(stackPos);
					});
				});
			} else {
				el.bind($.fieldEvent(el, delay), function(){
					observed = window.delayedObserverStack[stackPos];
					if (observed.obj.formVal() == observed.obj.oldVal) return;
					else window.delayedObserverCallback(stackPos);
				});
			};
		},
		formVal: function() { // Gets form values
			var el = this[0];
			if(el.tagName == 'FORM') return this.serialize();
			if(el.type == 'checkbox' || self.type == 'radio') return this.filter('input:checked').val() || '';
			else return this.val();
		}
	});
})(jQuery);

/*
*
* jRails visual effects stubs
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.fn.extend({
		visualEffect : function(o) {
			e = o.replace(/\_(.)/g, function(m, l){return l.toUpperCase()});
			return eval('$(this).'+e+'()');
		},
		appear : function(speed, callback) {
			return this.fadeIn(speed, callback);
		},
		blindDown : function(speed, callback) {
			return this.show('blind', { direction: 'vertical' }, speed, callback);
		},
		blindUp : function(speed, callback) {
			return this.hide('blind', { direction: 'vertical' }, speed, callback);
		},
		blindRight : function(speed, callback) {
			return this.show('blind', { direction: 'horizontal' }, speed, callback);
		},
		blindLeft : function(speed, callback) {
			this.hide('blind', { direction: 'horizontal' }, speed, callback);
			return this;
		},
		dropOut : function(speed, callback) {
			return this.hide('drop', {direction: 'down' }, speed, callback);
		},
		dropIn : function(speed, callback) {
			return this.show('drop', { direction: 'up' }, speed, callback);
		},
		fade : function(speed, callback) {
			return this.fadeOut(speed, callback);
		},
		fadeToggle : function(speed, callback) {
			return this.animate({opacity: 'toggle'}, speed, callback);
		},
		fold : function(speed, callback) {
			return this.hide('fold', {}, speed, callback);
		},
		foldOut : function(speed, callback) {
			return this.show('fold', {}, speed, callback);
		},
		grow : function(speed, callback) {
			return this.show('scale', {}, speed, callback);
		},
		highlight : function(speed, callback) {
			return this.show('highlight', {}, speed, callback);
		},
		puff : function(speed, callback) {
			return this.hide('puff', {}, speed, callback);
		},
		pulsate : function(speed, callback) {
			return this.show('pulsate', {}, speed, callback);
		},
		shake : function(speed, callback) {
			return this.show('shake', {}, speed, callback);
		},
		shrink : function(speed, callback) {
			return this.hide('scale', {}, speed, callback);
		},
		squish : function(speed, callback) {
			return this.hide('scale', { origin: ['top', 'left'] }, speed, callback);
		},
		slideUp : function(speed, callback) {
			return this.hide('slide', { direction: 'up'}, speed, callback);
		},
		slideDown : function(speed, callback) {
			return this.show('slide', { direction: 'up'}, speed, callback);
		},
		switchOff : function(speed, callback) {
			return this.hide('clip', {}, speed, callback);
		},
		switchOn : function(speed, callback) {
			return this.show('clip', {}, speed, callback);
		}
	});
})(jQuery);
<|endoftext|>


<commit_before>/*
*
* jRails ajax extras
* version 0.1
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$().ajaxSend(function(a, xhr, s){ //Set request headers globally
		xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
	});
})(jQuery);

/*
*
* jRails form extras
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	// reset a form
	$.fn.reset = function() {
		return this.each(function() {
			// guard against an input with the name of 'reset'
			// note that IE reports the reset function as an 'object'
			if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
				this.reset();
		});
	};
	// enable a form element
	$.fn.enable = function() {
		return this.each(function() {
			this.disabled = false;
		});
	};
	// disable a form element
	$.fn.disable = function() {
		return this.each(function() {
			this.disabled = true;
		});
	};

})(jQuery);

/*
*
* jRails form observer plugin
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.extend({ // Translate field to event
		fieldEvent: function(el, obs) {
			var field = el[0] || el, e = 'change';
			if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
			else if (obs && field.type == 'text' || field.type == 'textarea') e = 'keyup';
			return e;
		}
	});
	$.fn.extend({ // Delayed observer for fields and forms
		delayedObserver: function(delay, callback){
			var el = $(this);
			if (typeof window.delayedObserverStack == 'undefined') window.delayedObserverStack = [];
			if (typeof window.delayedObserverCallback == 'undefined') {
				window.delayedObserverCallback = function(stackPos) {
					observed = window.delayedObserverStack[stackPos];
					if (observed.timer) clearTimeout(observed.timer);
					observed.timer = setTimeout(function(){
						observed.timer = null;
						observed.callback(observed.obj, observed.obj.formVal());
					}, observed.delay * 1000);
					observed.oldVal = observed.obj.formVal();
				}
			}
			window.delayedObserverStack.push({
				obj: el, timer: null, delay: delay,
				oldVal: el.formVal(), callback: callback
			});
			var stackPos = window.delayedObserverStack.length-1;
			if (el[0].tagName == 'FORM') {
				$(':input', el).each(function(){
					var field = $(this);
					field.bind($.fieldEvent(field, delay), function(){
						observed = window.delayedObserverStack[stackPos];
						if (observed.obj.formVal() == observed.oldVal) return;
						else window.delayedObserverCallback(stackPos);
					});
				});
			} else {
				el.bind($.fieldEvent(el, delay), function(){
					observed = window.delayedObserverStack[stackPos];
					if (observed.obj.formVal() == observed.oldVal) return;
					else window.delayedObserverCallback(stackPos);
				});
			};
		},
		formVal: function() { // Gets form values
			var el = this[0];
			if(el.tagName == 'FORM') return this.serialize();
			if(el.type == 'checkbox' || el.type == 'radio') return this.filter('input:checked').val() || '';
			else return this.val();
		}
	});
})(jQuery);

/*
*
* jRails visual effects stubs
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.fn.extend({
		visualEffect : function(o) {
			e = o.replace(/\_(.)/g, function(m, l){return l.toUpperCase()});
			return eval('$(this).'+e+'()');
		},
		appear : function(speed, callback) {
			return this.fadeIn(speed, callback);
		},
		blindDown : function(speed, callback) {
			return this.show('blind', { direction: 'vertical' }, speed, callback);
		},
		blindUp : function(speed, callback) {
			return this.hide('blind', { direction: 'vertical' }, speed, callback);
		},
		blindRight : function(speed, callback) {
			return this.show('blind', { direction: 'horizontal' }, speed, callback);
		},
		blindLeft : function(speed, callback) {
			this.hide('blind', { direction: 'horizontal' }, speed, callback);
			return this;
		},
		dropOut : function(speed, callback) {
			return this.hide('drop', {direction: 'down' }, speed, callback);
		},
		dropIn : function(speed, callback) {
			return this.show('drop', { direction: 'up' }, speed, callback);
		},
		fade : function(speed, callback) {
			return this.fadeOut(speed, callback);
		},
		fadeToggle : function(speed, callback) {
			return this.animate({opacity: 'toggle'}, speed, callback);
		},
		fold : function(speed, callback) {
			return this.hide('fold', {}, speed, callback);
		},
		foldOut : function(speed, callback) {
			return this.show('fold', {}, speed, callback);
		},
		grow : function(speed, callback) {
			return this.show('scale', {}, speed, callback);
		},
		highlight : function(speed, callback) {
			return this.show('highlight', {}, speed, callback);
		},
		puff : function(speed, callback) {
			return this.hide('puff', {}, speed, callback);
		},
		pulsate : function(speed, callback) {
			return this.show('pulsate', {}, speed, callback);
		},
		shake : function(speed, callback) {
			return this.show('shake', {}, speed, callback);
		},
		shrink : function(speed, callback) {
			return this.hide('scale', {}, speed, callback);
		},
		squish : function(speed, callback) {
			return this.hide('scale', { origin: ['top', 'left'] }, speed, callback);
		},
		slideUp : function(speed, callback) {
			return this.hide('slide', { direction: 'up'}, speed, callback);
		},
		slideDown : function(speed, callback) {
			return this.show('slide', { direction: 'up'}, speed, callback);
		},
		switchOff : function(speed, callback) {
			return this.hide('clip', {}, speed, callback);
		},
		switchOn : function(speed, callback) {
			return this.show('clip', {}, speed, callback);
		}
	});
})(jQuery);
<commit_msg>declare with 'var' for local variables<commit_after>/*
*
* jRails ajax extras
* version 0.1
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$().ajaxSend(function(a, xhr, s){ //Set request headers globally
		xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
	});
})(jQuery);

/*
*
* jRails form extras
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	// reset a form
	$.fn.reset = function() {
		return this.each(function() {
			// guard against an input with the name of 'reset'
			// note that IE reports the reset function as an 'object'
			if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
				this.reset();
		});
	};
	// enable a form element
	$.fn.enable = function() {
		return this.each(function() {
			this.disabled = false;
		});
	};
	// disable a form element
	$.fn.disable = function() {
		return this.each(function() {
			this.disabled = true;
		});
	};

})(jQuery);

/*
*
* jRails form observer plugin
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.extend({ // Translate field to event
		fieldEvent: function(el, obs) {
			var field = el[0] || el, e = 'change';
			if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
			else if (obs && field.type == 'text' || field.type == 'textarea') e = 'keyup';
			return e;
		}
	});
	$.fn.extend({ // Delayed observer for fields and forms
		delayedObserver: function(delay, callback){
			var el = $(this);
			if (typeof window.delayedObserverStack == 'undefined') window.delayedObserverStack = [];
			if (typeof window.delayedObserverCallback == 'undefined') {
				window.delayedObserverCallback = function(stackPos) {
					var observed = window.delayedObserverStack[stackPos];
					if (observed.timer) clearTimeout(observed.timer);
					observed.timer = setTimeout(function(){
						observed.timer = null;
						observed.callback(observed.obj, observed.obj.formVal());
					}, observed.delay * 1000);
					observed.oldVal = observed.obj.formVal();
				};
			}
			window.delayedObserverStack.push({
				obj: el, timer: null, delay: delay,
				oldVal: el.formVal(), callback: callback
			});
			var stackPos = window.delayedObserverStack.length-1;
			if (el[0].tagName == 'FORM') {
				$(':input', el).each(function(){
					var field = $(this);
					field.bind($.fieldEvent(field, delay), function(){
						var observed = window.delayedObserverStack[stackPos];
						if (observed.obj.formVal() == observed.oldVal) return;
						else window.delayedObserverCallback(stackPos);
					});
				});
			} else {
				el.bind($.fieldEvent(el, delay), function(){
					var observed = window.delayedObserverStack[stackPos];
					if (observed.obj.formVal() == observed.oldVal) return;
					else window.delayedObserverCallback(stackPos);
				});
			};
		},
		formVal: function() { // Gets form values
			var el = this[0];
			if(el.tagName == 'FORM') return this.serialize();
			if(el.type == 'checkbox' || el.type == 'radio') return this.filter('input:checked').val() || '';
			else return this.val();
		}
	});
})(jQuery);

/*
*
* jRails visual effects stubs
* version 0.2
* <aaron@ennerchi.com> | http://www.ennerchi.com
*
*/

(function($) {
	$.fn.extend({
		visualEffect : function(o) {
			e = o.replace(/\_(.)/g, function(m, l){return l.toUpperCase()});
			return eval('$(this).'+e+'()');
		},
		appear : function(speed, callback) {
			return this.fadeIn(speed, callback);
		},
		blindDown : function(speed, callback) {
			return this.show('blind', { direction: 'vertical' }, speed, callback);
		},
		blindUp : function(speed, callback) {
			return this.hide('blind', { direction: 'vertical' }, speed, callback);
		},
		blindRight : function(speed, callback) {
			return this.show('blind', { direction: 'horizontal' }, speed, callback);
		},
		blindLeft : function(speed, callback) {
			this.hide('blind', { direction: 'horizontal' }, speed, callback);
			return this;
		},
		dropOut : function(speed, callback) {
			return this.hide('drop', {direction: 'down' }, speed, callback);
		},
		dropIn : function(speed, callback) {
			return this.show('drop', { direction: 'up' }, speed, callback);
		},
		fade : function(speed, callback) {
			return this.fadeOut(speed, callback);
		},
		fadeToggle : function(speed, callback) {
			return this.animate({opacity: 'toggle'}, speed, callback);
		},
		fold : function(speed, callback) {
			return this.hide('fold', {}, speed, callback);
		},
		foldOut : function(speed, callback) {
			return this.show('fold', {}, speed, callback);
		},
		grow : function(speed, callback) {
			return this.show('scale', {}, speed, callback);
		},
		highlight : function(speed, callback) {
			return this.show('highlight', {}, speed, callback);
		},
		puff : function(speed, callback) {
			return this.hide('puff', {}, speed, callback);
		},
		pulsate : function(speed, callback) {
			return this.show('pulsate', {}, speed, callback);
		},
		shake : function(speed, callback) {
			return this.show('shake', {}, speed, callback);
		},
		shrink : function(speed, callback) {
			return this.hide('scale', {}, speed, callback);
		},
		squish : function(speed, callback) {
			return this.hide('scale', { origin: ['top', 'left'] }, speed, callback);
		},
		slideUp : function(speed, callback) {
			return this.hide('slide', { direction: 'up'}, speed, callback);
		},
		slideDown : function(speed, callback) {
			return this.show('slide', { direction: 'up'}, speed, callback);
		},
		switchOff : function(speed, callback) {
			return this.hide('clip', {}, speed, callback);
		},
		switchOn : function(speed, callback) {
			return this.show('clip', {}, speed, callback);
		}
	});
})(jQuery);
<|endoftext|>


<commit_before>'use strict';

const {isFunction, isDefined, assert, deepCopy, isBrowser, makeBus} = require('@okwolo/utils')();

const version = '1.3.0';

const core = ({modules, blobs, options}) => {
    const okwolo = (target, _window) => {
        if (options.browser) {
            if (!isDefined(_window)) {
                assert(isBrowser(), 'app : must be run in a browser environment');
                _window = window;
            }
        }

        const emit = makeBus();
        const use = makeBus();
        const api = {emit, use};

        modules.forEach((_module) => {
            _module({emit, use}, _window);
        });

        blobs.forEach((blob) => {
            use(blob(_window));
        });

        const initial = {};
        let _state = initial;

        emit.on('state', (newState) => {
            _state = newState;
        });

        api.getState = () => {
            assert(_state !== initial, 'getState : cannot get state before it has been set');
            return deepCopy(_state);
        };

        if (options.modules.dom) {
            api.update = () => {
                emit({state: _state});
            };

            if (isDefined(target)) {
                use({target});
            }
        }

        if (options.modules.state) {
            api.act = (type, params) => {
                assert(type === 'SET_STATE' || _state !== initial, 'act : cannot act on state before it has been set');
                emit({act: {state: _state, type, params}});
            };

            use({action: {
                type: 'SET_STATE',
                target: [],
                handler: (state, params) => params,
            }});

            api.setState = (replacement) => {
                if (isFunction(replacement)) {
                    api.act('SET_STATE', replacement(deepCopy(_state)));
                    return;
                }
                api.act('SET_STATE', replacement);
            };

            if (options.modules.history) {
                api.undo = () => {
                    api.act('UNDO');
                };

                api.redo = () => {
                    api.act('REDO');
                };
            }
        } else {
            assert(!options.modules.history, 'app : cannot use history blob without the state module', options);
            api.setState = (replacement) => {
                if (isFunction(replacement)) {
                    emit({state: replacement(deepCopy(_state))});
                    return;
                }
                emit({state: replacement});
            };
        }

        if (options.modules.router) {
            api.redirect = (path, params) => {
                emit({redirect: {path, params}});
            };

            api.show = (path, params) => {
                emit({show: {path, params}});
            };

            api.register = (path, builder) => {
                if (isFunction(path)) {
                    use({builder: path()});
                    return;
                }
                use({route: {
                    path,
                    handler: (params) => {
                        use({builder: builder(params)});
                    },
                }});
            };
        } else {
            api.register = (builder) => {
                use({builder: builder()});
                return;
            };
        }

        return Object.assign(api.register, api);
    };

    if (isBrowser()) {
        okwolo.kit = options.kit;
        okwolo.version = version;
        if (!isDefined(window.okwolo)) {
            window.okwolo = okwolo;
        }
        window.okwolo[options.kit] = okwolo;
    }

    return okwolo;
};

module.exports = core;
<commit_msg>added comments to core<commit_after>'use strict';

const {isFunction, isDefined, assert, deepCopy, isBrowser, makeBus} = require('@okwolo/utils')();

// version cannot be taken from package.json because environment is not guaranteed.
const version = '1.3.0';

const core = ({modules, blobs, options}) => {
    // if it is needed to define the window but not yet add a target, the first
    // argument can be set to undefined.
    const okwolo = (target, _window) => {
        // if the kit requires the browser api, there must be a window object in
        // scope or a window object must be injected as argument.
        if (options.browser) {
            if (!isDefined(_window)) {
                assert(isBrowser(), 'app : must be run in a browser environment');
                _window = window;
            }
        }

        const emit = makeBus();
        const use = makeBus();

        // the api object will contain all the exposed functions/variables.
        const api = {emit, use};

        // each module is instantiated.
        modules.forEach((_module) => {
            _module({emit, use}, _window);
        });

        // each blob is used.
        blobs.forEach((blob) => {
            use(blob(_window));
        });

        // reference to initial state is kept to be able to track whether it
        // has changed using strict equality.
        const initial = {};
        let _state = initial;

        // current state is monitored and stored.
        emit.on('state', (newState) => {
            _state = newState;
        });

        api.getState = () => {
            assert(_state !== initial, 'getState : cannot get state before it has been set');
            return deepCopy(_state);
        };

        // the only functionality from the dom module that is directly exposed
        // is the update event.
        if (options.modules.dom) {
            api.update = () => {
                emit({state: _state});
            };

            // target is used if it is defined, but this step can be deferred
            // if it is not convenient to pass the target on app creation.
            if (isDefined(target)) {
                use({target});
            }
        }

        if (options.modules.state) {
            api.act = (type, params) => {
                // the only action that does not need the state to have already
                // been changed is SET_STATE
                assert(_state !== initial || type === 'SET_STATE', 'act : cannot act on state before it has been set');
                emit({act: {state: _state, type, params}});
            };

            // action is used to override state in order to give visibility to
            // watchers and middleware.
            use({action: {
                type: 'SET_STATE',
                target: [],
                handler: (state, params) => params,
            }});

            api.setState = (replacement) => {
                if (isFunction(replacement)) {
                    api.act('SET_STATE', replacement(_state));
                    return;
                }
                api.act('SET_STATE', replacement);
            };
        } else {
            // new state is emitted directly instead of giving that responsibility
            // to the state module.
            api.setState = (replacement) => {
                if (isFunction(replacement)) {
                    emit({state: replacement(deepCopy(_state))});
                    return;
                }
                emit({state: replacement});
            };
        }

        if (options.modules.history) {
            assert(options.modules.state, 'app : cannot use history blob without the state module', options);

            api.undo = () => {
                api.act('UNDO');
            };

            api.redo = () => {
                api.act('REDO');
            };
        }

        if (options.modules.router) {
            api.redirect = (path, params) => {
                emit({redirect: {path, params}});
            };

            api.show = (path, params) => {
                emit({show: {path, params}});
            };

            // first argument can be a path string to register a route handler
            // or a function to directly use a builder.
            api.register = (path, builder) => {
                if (isFunction(path)) {
                    use({builder: path()});
                    return;
                }
                use({route: {
                    path,
                    handler: (params) => {
                        use({builder: builder(params)});
                    },
                }});
            };
        } else {
            api.register = (builder) => {
                use({builder: builder()});
                return;
            };
        }

        // the returned object contains all the keys added to the api object
        // but is also the register function.
        return Object.assign(api.register, api);
    };

    // okwolo attempts to define itself globally and includes information about
    // the version number and kit name. note that different kits can coexist,
    // but not two kits with the same name and different versions.
    if (isBrowser()) {
        okwolo.kit = options.kit;
        okwolo.version = version;
        if (!isDefined(window.okwolo)) {
            window.okwolo = okwolo;
        }
        window.okwolo[options.kit] = okwolo;
    }

    return okwolo;
};

module.exports = core;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed 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.
 */

/** A method that is configured to call a service over HTTP. No code or
  function body is required here, as the actual body is generated to call
  the remote service. This will always return a promise that supplies the
  return value of the service call.

Overriding by an XHRMethod is not supported. You can override an
  XHRMethod with a normal one.

FUTURE: Generalize. */
foam.CLASS({
  package: 'foam.api',
  name: 'XHRMethod',
  extends: 'foam.core.Method',
  requires: [
    'foam.api.XHRArgument',
    'foam.core.Imports',
  ],
  imports: [
    'assert',
  ],

  properties: [
    {
      /** The path prefix. Parameters may add to the path */
      name: 'path'
    },
    {
      name: 'httpMethod',
      value: 'GET',
    },
    {
      /** The parameters to call with, in order */
      class: 'FObjectArray',
      name: 'parameters',
      of: 'foam.api.XHRArgument',
      factory: function() { return []; }
    },
    {
      /** XHRMethods will always return a Promise, but the Promise will pass
        along a parameter of the type specified here. */
      name: 'returns',
    },
    {
      /** the name of the XHR service to import at run time */
      name: 'xhrServiceName',
      value: 'XHRService'
    }
  ],

  methods: [
    function installInClass(c) {
      // add an import for the XHRService on our host class

      // May have many XHRMethods in a host class, but only do service import once.
      var existing = c.getAxiomByName(this.xhrServiceName);
      this.assert( ( ! existing ) || this.Imports.isInstance(existing),
        "XHRMethod installInClass found conflicting axiom", existing && existing.name, ".",
        "Use a different XMRMethod.xhrServiceName.");

      if ( ! existing ) {
        c.installAxiom(this.Imports.create({
          name: this.xhrServiceName,
          key: this.xhrServiceName
        }));
      }
    },

    function installInProto(p) {
      // generate body to call through to xhr
      var axiom = this;

      // TODO: just import the thing that does the xhr, preconfigured

      // set up function with correct args, pass them into the
      // actual implementation, callRemote_()
      // ALTERNATE: just pass args in and read from arguments
      var code = "(function "+axiom.name+"_"+"(";
      var names = this.parameters.map(axiom.XHRArgument.NAME.f);
      code += names.join(', ');
      code += ') {\n';
      code += 'var opt_args = {\n';
      names.forEach(function(name) {
        code += '  '+name+': '+name+',\n';
      });
      code += '};\n';
      code += 'return axiom.callRemote_(opt_args, this);\n';
      code += '})';

      code = eval(code);

      p[axiom.name] = code;
      console.log('installed XHRMethod', axiom.name, code, p[axiom.name]);

    },

    function callRemote_(/* object */ opt_args, host /* Promise */) {
      this.assert( host[this.xhrServiceName], "XHRMethod call can't find XHR service import ", this.xhrServiceName, "on", host);

      // 'this' is the axiom instance
      var self = this;
      var path = this.path;
      var query = "";

      // add on parameters passed as part of the path or query
      self.parameters.forEach(function(param) {
        var val = opt_args[param.name].toString();
        // put the dot back if we removed one from the name
        var pname = param.name.replace('__dot__','.');
        if ( param.location === 'path' ) {
          // find the placeholder and replace it
          path = path.replace("{"+pname+"}", val);
        } else if ( param.location === 'query' ) {
          query += "&" + pname + "=" + val;
        }
      });
      path = path + ( query ? "?" + query.substring(1) : "" );
      var request = host[this.xhrServiceName].create({
        path: path,
        method: self.httpMethod
      });

      return request.send().then(function(response) {
        self.assert(response.responseType === 'json', "XHRMethod given a request not configured to return JSON", request);
        return response.payload.then(function(json) {
          if ( ! self.returns ) {
            // no return
            return;
          }
          if ( self.returns.type ) {
            // a modelled return type
            return self.returns.type.create(json, host);
          }
          // else return raw json
          return json;
        });
      });
    },

  ]

});

foam.CLASS({
  package: 'foam.api',
  name: 'XHRArgument',
  extends: 'foam.core.Argument',
  properties: [
    {
      /** The location to put this value in the request: 'query' or 'path' */
      name: 'location',
      value: 'query',
    },
    // optional
  ],
 });
<commit_msg>XHRMethod fixed path<commit_after>/**
 * @license
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed 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.
 */

/** A method that is configured to call a service over HTTP. No code or
  function body is required here, as the actual body is generated to call
  the remote service. This will always return a promise that supplies the
  return value of the service call.

Overriding by an XHRMethod is not supported. You can override an
  XHRMethod with a normal one.

FUTURE: Generalize. */
foam.CLASS({
  package: 'foam.api',
  name: 'XHRMethod',
  extends: 'foam.core.Method',
  requires: [
    'foam.api.XHRArgument',
    'foam.core.Imports',
  ],
  imports: [
    'assert',
  ],

  properties: [
    {
      /** The path prefix. Parameters may add to the path */
      name: 'path'
    },
    {
      name: 'httpMethod',
      value: 'GET',
    },
    {
      /** The parameters to call with, in order */
      class: 'FObjectArray',
      name: 'parameters',
      of: 'foam.api.XHRArgument',
      factory: function() { return []; }
    },
    {
      /** XHRMethods will always return a Promise, but the Promise will pass
        along a parameter of the type specified here. */
      name: 'returns',
    },
    {
      /** the name of the XHR service to import at run time */
      name: 'xhrServiceName',
      value: 'XHRService'
    }
  ],

  methods: [
    function installInClass(c) {
      // add an import for the XHRService on our host class

      // May have many XHRMethods in a host class, but only do service import once.
      var existing = c.getAxiomByName(this.xhrServiceName);
      this.assert( ( ! existing ) || this.Imports.isInstance(existing),
        "XHRMethod installInClass found conflicting axiom", existing && existing.name, ".",
        "Use a different XMRMethod.xhrServiceName.");

      if ( ! existing ) {
        c.installAxiom(this.Imports.create({
          name: this.xhrServiceName,
          key: this.xhrServiceName
        }));
      }
    },

    function installInProto(p) {
      // generate body to call through to xhr
      var axiom = this;

      // TODO: just import the thing that does the xhr, preconfigured

      // set up function with correct args, pass them into the
      // actual implementation, callRemote_()
      // ALTERNATE: just pass args in and read from arguments
      var code = "(function "+axiom.name+"_"+"(";
      var names = this.parameters.map(axiom.XHRArgument.NAME.f);
      code += names.join(', ');
      code += ') {\n';
      code += 'var opt_args = {\n';
      names.forEach(function(name) {
        code += '  '+name+': '+name+',\n';
      });
      code += '};\n';
      code += 'return axiom.callRemote_(opt_args, this);\n';
      code += '})';

      code = eval(code);

      p[axiom.name] = code;
    },

    function callRemote_(/* object */ opt_args, host /* Promise */) {
      this.assert( host[this.xhrServiceName], "XHRMethod call can't find XHR service import ", this.xhrServiceName, "on", host);

      // 'this' is the axiom instance
      var self = this;
      var path = this.path;
      var query = "";

      // add on parameters passed as part of the path or query
      self.parameters.forEach(function(param) {
        var val = opt_args[param.name].toString();
        // put the dot back if we removed one from the name
        var pname = param.name.replace('__dot__','.');
        if ( param.location === 'path' ) {
          // find the placeholder and replace it
          path = path.replace("{"+pname+"}", val);
        } else if ( param.location === 'query' ) {
          query += "&" + pname + "=" + val;
        }
      });
      path = path + ( query ? "?" + query.substring(1) : "" );
      var request = host[this.xhrServiceName].create();
      request.path += "/" + path;
      request.method = self.httpMethod;

      return request.send().then(function(response) {
        self.assert(response.responseType === 'json', "XHRMethod given a request not configured to return JSON", request);
        return response.payload.then(function(json) {
          if ( ! self.returns ) {
            // no return
            return;
          }
          if ( self.returns.type ) {
            // a modelled return type
            return self.returns.type.create(json, host);
          }
          // else return raw json
          return json;
        });
      });
    },

  ]

});

foam.CLASS({
  package: 'foam.api',
  name: 'XHRArgument',
  extends: 'foam.core.Argument',
  properties: [
    {
      /** The location to put this value in the request: 'query' or 'path' */
      name: 'location',
      value: 'query',
    },
    // optional
  ],
 });
<|endoftext|>


<commit_before>module.exports = function(skill, info, bot, message, db) {
    var userData = message.text.match(/\<(.*?)\>/g);
    console.log('messaage text: ' + message.text);
    console.log('userdata' + userData);
  if (userData) {
    // if there is a user named send ze hugs!
    //for (var i = 0, len = userData.length; i < len; i++) {
        //FU(userData[i].replace(/[^\w\s]/gi, ''));
        //console.log('userdata[i]' + userData[i]);
        //console.log('userdata[i]' + userData[i].replace(/[^\w\s]/gi, ''));
    //}
    console.log(userData[0].replace(/[^\w\s]/gi, ''));
    bot.reply(message, getSlackName(message.user.replace(/[^\w\s]/gi, '')) + ' has challenged ' + getSlackName(userData[0].replace(/[^\w\s]/gi, '')));

    //bot.reply(message,'Let\'s rumble' + userData[0].replace(/[^\w\s]/gi, ''));
  } else {
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function getSlackName(userID) {
    var slackName;
    bot.api.users.info({user: userID}, (error, response) => {
    console.log(response.user.real_name);
    slackName = JSON.stringify(response.user.name);
    })
    console.log('slackname: ' + slackName)
    return slackName;
}

function FU(user) {
    //DM some shade!
    bot.api.im.open({ user: user }, function (err, response) {
      if (err) {
        return console.log(err)
      }
    var fuckArray = [
    'https://giphy.com/gifs/cheezburger-olympics-U7P2vnWfPkIQ8',
    'https://giphy.com/gifs/louis-ck-middle-finger-fuck-you-Qd71uU3LzyxXO'
    ];
    var randomFuck = Math.floor(Math.random()* fuckArray.length);

    var dmChannel = response.channel.id
    bot.say({channel: dmChannel, text: 'Someone is throwing shade your way... :middle_finger:'})
    bot.say({channel: dmChannel, text: fuckArray[randomFuck]})
    })

}

  var gameEngine = require('./Rock-Paper-Spock');

    bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    })

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "spock"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.addPlayer({id: 3, sign: "spock"});
  instance.addPlayer(4, "rock").addPlayer(5, "paper");
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<commit_msg>Update RockPaperScissors.js<commit_after>module.exports = function(skill, info, bot, message, db) {
    var userData = message.text.match(/\<(.*?)\>/g);
    console.log('messaage text: ' + message.text);
    console.log('userdata' + userData);
  if (userData) {
    // if there is a user named send ze hugs!
    //for (var i = 0, len = userData.length; i < len; i++) {
        //FU(userData[i].replace(/[^\w\s]/gi, ''));
        //console.log('userdata[i]' + userData[i]);
        //console.log('userdata[i]' + userData[i].replace(/[^\w\s]/gi, ''));
    //}
    console.log(userData[0].replace(/[^\w\s]/gi, ''));
    bot.reply(message, getSlackName(message.user.replace(/[^\w\s]/gi, '')) + ' has challenged ' + getSlackName(userData[0].replace(/[^\w\s]/gi, '')));

    //bot.reply(message,'Let\'s rumble' + userData[0].replace(/[^\w\s]/gi, ''));
  } else {
    bot.reply(message, 'You didn\'t challenge anyone you chicken shit! :chicken: :poop:');
  }

function getSlackName(userID) {
    var slackName;
    bot.api.users.info({user: userID}, (error, response) => {
    console.log(response.user.real_name);
    return response.user.real_name;
    //slackName = JSON.stringify(response.user.name);
    })
    //console.log('slackname: ' + slackName)
    //return slackName;
}

function FU(user) {
    //DM some shade!
    bot.api.im.open({ user: user }, function (err, response) {
      if (err) {
        return console.log(err)
      }
    var fuckArray = [
    'https://giphy.com/gifs/cheezburger-olympics-U7P2vnWfPkIQ8',
    'https://giphy.com/gifs/louis-ck-middle-finger-fuck-you-Qd71uU3LzyxXO'
    ];
    var randomFuck = Math.floor(Math.random()* fuckArray.length);

    var dmChannel = response.channel.id
    bot.say({channel: dmChannel, text: 'Someone is throwing shade your way... :middle_finger:'})
    bot.say({channel: dmChannel, text: fuckArray[randomFuck]})
    })

}

  var gameEngine = require('./Rock-Paper-Spock');

    bot.api.users.info({user: message.user}, (error, response) => {
        //bot.reply(message, 'Rock Paper Scissors (lizard, spock, spiderman, batman, wizard, glock?)');
    })

  var instance = new gameEngine(gameEngine.DefaultRules);
  instance.addPlayer({id: 1, sign: "spock"});
  instance.addPlayer({id: 2, sign: "rock"});
  instance.addPlayer({id: 3, sign: "spock"});
  instance.addPlayer(4, "rock").addPlayer(5, "paper");
  instance.play();
  console.log(instance.winner);
  //note players that won-lost, add support for W-L records
  //bot.reply(message, 'test successful. maybe code something more useful next time?');
};
<|endoftext|>


<commit_before>export default {
  name: 'ElRow',

  componentName: 'ElRow',

  props: {
    tag: {
      type: String,
      default: 'div'
    },
    gutter: Number,
    type: String,
    justify: {
      type: String,
      default: 'start'
    },
    align: {
      type: String,
      default: 'top'
    }
  },

  computed: {
    style() {
      var ret = {};

      if (this.gutter) {
        ret.marginLeft = `-${this.gutter / 2}px`;
        ret.marginRight = ret.marginLeft;
      }

      return ret;
    }
  },

  render(h) {
    return h(this.tag, {
      class: [
        'el-row',
        justify !== 'start' ? `is-justify-${this.justify}` : '',
        align !== 'top' ? `is-align-${this.align}` : '',
        { 'el-row--flex': this.type === 'flex' }
      ],
      style: this.style
    }, this.$slots.default);
  }
};
<commit_msg>Update row.js<commit_after>export default {
  name: 'ElRow',

  componentName: 'ElRow',

  props: {
    tag: {
      type: String,
      default: 'div'
    },
    gutter: Number,
    type: String,
    justify: {
      type: String,
      default: 'start'
    },
    align: {
      type: String,
      default: 'top'
    }
  },

  computed: {
    style() {
      var ret = {};

      if (this.gutter) {
        ret.marginLeft = `-${this.gutter / 2}px`;
        ret.marginRight = ret.marginLeft;
      }

      return ret;
    }
  },

  render(h) {
    return h(this.tag, {
      class: [
        'el-row',
        this.justify !== 'start' ? `is-justify-${this.justify}` : '',
        this.align !== 'top' ? `is-align-${this.align}` : '',
        { 'el-row--flex': this.type === 'flex' }
      ],
      style: this.style
    }, this.$slots.default);
  }
};
<|endoftext|>