<commit_before>/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, describe: false, beforeEach: false, afterEach: false, it: false, runs: false, waitsFor: false, expect: false, brackets: false */

define(function (require, exports, module) {
    'use strict';

    // Load dependent modules
    var KeyMap = require("KeyMap");

    describe("KeyMap", function () {

        beforeEach(function () {
        });

        afterEach(function () {
        });

        it("should normalize keyboard modifiers", function () {
            var testKeyMap = KeyMap.create({
                "Ctrl-Alt-Shift-Q": "test.correct_order",
                "Shift-Ctrl-Alt-W": "test.reversed_order",
                "Ctrl-Shift-Alt-E": "test.mixed_order"
            });
            var expectedKeyMap = KeyMap.create({
                "Ctrl-Alt-Shift-Q": "test.correct_order",
                "Ctrl-Alt-Shift-W": "test.reversed_order",
                "Ctrl-Alt-Shift-E": "test.mixed_order"
            });
            expect(testKeyMap).toEqual(expectedKeyMap);
        });

    });
});
<commit_msg>Update Unit Tests<commit_after>/*
 * Copyright 2012 Adobe Systems Incorporated. All Rights Reserved.
 */

/*jslint vars: true, plusplus: true, devel: true, browser: true, nomen: true, indent: 4, maxerr: 50 */
/*global define: false, describe: false, beforeEach: false, afterEach: false, it: false, runs: false, waitsFor: false, expect: false, brackets: false */

define(function (require, exports, module) {
    'use strict';

    // Load dependent modules
    var KeyMap = require("KeyMap");

    describe("KeyMap", function () {

        beforeEach(function () {
        });

        afterEach(function () {
        });

        it("should normalize keyboard modifiers", function () {
            var testKeyMap = KeyMap.create({
                "bindings": [
                    {"Ctrl-Alt-Shift-Q": "test.correct_order"},
                    {"Shift-Ctrl-Alt-W": "test.reversed_order"},
                    {"Ctrl-Shift-Alt-E": "test.mixed_order"}
                ]
            });
            var expectedKeyMap = KeyMap.create({
                "bindings": [
                    {"Ctrl-Alt-Shift-Q": "test.correct_order"},
                    {"Ctrl-Alt-Shift-W": "test.reversed_order"},
                    {"Ctrl-Alt-Shift-E": "test.mixed_order"}
                ]
            });
            expect(testKeyMap).toEqual(expectedKeyMap);
        });

        it("should filter base on platform", function () {
            var testKeyMap = KeyMap.create({
                "bindings": [
                    {"Ctrl-B": "test.both"},
                    {"Ctrl-M": "test.mac", "platform": "mac"},
                    {"Ctrl-W": "test.win", "platform": "win"}
                ],
                "platform": "mac"
            });
            var expectedKeyMap = KeyMap.create({
                "bindings": [
                    {"Ctrl-B": "test.both"},
                    {"Ctrl-M": "test.mac"}
                ]
            });
            expect(testKeyMap).toEqual(expectedKeyMap);
        });

    });
});
<|endoftext|>


<commit_before>/*jslint browser: true*/
/*global $, jQuery, alert, FileReader */

var game = {};
var daily = {};
var prompt = {};

game.init = function () {
    'use strict';
    if (game.gamedata === null) {
        return;
    }

    $('#game').fadeIn(1000);
    $('#options').hide();
    $('#stats').show();

    game.teams = [];
    $(".team").each(function () {
        game.teams.push({
            "name": $(this).val(),
            "points": 0
        });
    });
    game.createScoreboard();
    game.current_points = 0;
};

game.createScoreboard = function () {
    'use strict';

    var i, content;

    content = "

";
    for (i = 0; i < game.teams.length; i = i + 1) {
        content += "
" + game.teams[i].name + "
	";
    }

    content += "

";
    for (i = 0; i < game.teams.length; i = i + 1) {
        content += "
0
<input class='add-points' onclick='game.addPoints(" + i + ")' value='+' type='button' /><input class='subtract-points' onclick='game.subtractPoints(" + i + ")' type='button' value='-' />	";
    }

    content += "

";
    $('#stats').html(content);
};

game.addPoints = function (team) {
    'use strict';
    game.updatePoints(team, game.current_points);
};

game.subtractPoints = function (team) {
    'use strict';
    var points = -game.current_points;
    game.updatePoints(team, points);
};

game.updatePoints = function (team, diff) {
    'use strict';
    game.teams[team].points += diff;

    $('#team' + team).html(game.teams[team].points);
    $('#' + game.current_questionID)
        .addClass("dirty")
        .unbind('mouseover')
        .unbind('mouseout')
        .unbind('click');

    game.current_points = 0;
};

game.loadFile = function (onload) {
    'use strict';
    if (typeof window.FileReader !== 'function') {
        return;
    }

    var fr, input = document.getElementById('fileinput');
    if (input && input.files && input.files[0]) {
        fr = new FileReader();
        fr.onload = onload;
        fr.readAsText(input.files[0]);
    }
};

game.extractFromId = function (identifier, index) {
    'use strict';
    var retval, regexp = /c([0-9])r([0-9])/g;
    retval = regexp.exec(identifier);
    return retval[index];
};

prompt.show = function (field) {
    'use strict';
    game.current_points = parseInt(field.find('h3').text(), 10);
    game.current_questionID = field.attr("id");
    var column, row, dataset, question, answer;
    column = game.extractFromId(field.attr("id"), 1) - 1;
    row = game.extractFromId(field.attr("id"), 2) - 1;
    dataset = game.gamedata.data[column].data[row];

    $('#game').hide();

    if (dataset.hasOwnProperty("daily")) {
        if (game.points_bet) {
            game.current_points = parseInt(game.points_bet, 10);
            game.points_bet = null;
        } else {
            daily.show(field);
            return;
        }
    }

    question = prompt.loadImage(dataset.question);
    answer = prompt.loadImage(dataset.answer);

    $('#question').hide();
    $('#prompt').fadeIn(1000);
    $('#answer').html(question);
    $('#question').html(answer);
    if ($('#question').html().length === 0) {
        $('#correct-response').hide();
    } else {
        $('#correct-response').show();
    }
};

prompt.loadImage = function (image) {
    'use strict';
    var prefix = game.gamedata.directory;
    if (image.substring(0, 6) === "image:") {
        return "";
    }
    return image;
};

prompt.hide = function () {
    'use strict';
    $('#prompt').hide();
    $('#game').show();
};

prompt.showQuestion = function () {
    'use strict';
    $('#question').fadeIn(1000);
};

daily.show = function (field) {
    'use strict';
    $('#prompt').hide();
    $('#daily').show();

    $('#bet_submit').click(function () {
        game.points_bet = $("#bet").val();
        game.current_points = game.points_bet;
        prompt.show(field);
        $('#daily').hide();
    });
};

$(document).ready(function () {
    'use strict';
    $('tbody tr td').each(function () {
        $(this).addClass('cell')
            .click(function () {
                var field = $(this);
                if (!field.hasClass('dirty')) {
                    prompt.show(field);
                }
            });
    });

    $('textarea.edit').focus(function () {
        $(this).addClass('active');
        var val = $(this).val();
        if (val === "Enter Category" || val === "Enter Title") {
            this.select();
        }
    }).blur(function () {
        $(this).removeClass('active');
    }).autogrow();

    $('.clean').mouseover(function () {
        $(this).addClass('ie-hack');
    }).mouseout(function () {
        $(this).removeClass('ie-hack');
    });

    $('#fileinput').change(function () {
        game.loadFile(function (e) {
            var data, j;
            data = $.parseJSON(e.target.result);
            $('#title').html(data.name);
            $('#gametitle').html(data.name);
            j = 0;
            $('thead').find('th:not(#gametitle)').each(function () {
                var id, label;
                id = $(this).attr("id");
                label = data.data[j].name;
                $(this).html(label);
                j = j + 1;
            });
            game.gamedata = data;
        });
    });

    $("#add").click(function () {
        $("<input type=\"text\" name=\"team[]\" class=\"team\" />").appendTo("#teams");
    });
});
<commit_msg>unix line endings.<commit_after>/*jslint browser: true*/
/*global $, jQuery, alert, FileReader */

var game = {};
var daily = {};
var prompt = {};

game.init = function () {
    'use strict';
    if (game.gamedata === null) {
        return;
    }

    $('#game').fadeIn(1000);
    $('#options').hide();
    $('#stats').show();

    game.teams = [];
    $(".team").each(function () {
        game.teams.push({
            "name": $(this).val(),
            "points": 0
        });
    });
    game.createScoreboard();
    game.current_points = 0;
};

game.createScoreboard = function () {
    'use strict';

    var i, content;

    content = "

";
    for (i = 0; i < game.teams.length; i = i + 1) {
        content += "
" + game.teams[i].name + "
	";
    }

    content += "

";
    for (i = 0; i < game.teams.length; i = i + 1) {
        content += "
0
<input class='add-points' onclick='game.addPoints(" + i + ")' value='+' type='button' /><input class='subtract-points' onclick='game.subtractPoints(" + i + ")' type='button' value='-' />	";
    }

    content += "

";
    $('#stats').html(content);
};

game.addPoints = function (team) {
    'use strict';
    game.updatePoints(team, game.current_points);
};

game.subtractPoints = function (team) {
    'use strict';
    var points = -game.current_points;
    game.updatePoints(team, points);
};

game.updatePoints = function (team, diff) {
    'use strict';
    game.teams[team].points += diff;

    $('#team' + team).html(game.teams[team].points);
    $('#' + game.current_questionID)
        .addClass("dirty")
        .unbind('mouseover')
        .unbind('mouseout')
        .unbind('click');

    game.current_points = 0;
};

game.loadFile = function (onload) {
    'use strict';
    if (typeof window.FileReader !== 'function') {
        return;
    }

    var fr, input = document.getElementById('fileinput');
    if (input && input.files && input.files[0]) {
        fr = new FileReader();
        fr.onload = onload;
        fr.readAsText(input.files[0]);
    }
};

game.extractFromId = function (identifier, index) {
    'use strict';
    var retval, regexp = /c([0-9])r([0-9])/g;
    retval = regexp.exec(identifier);
    return retval[index];
};

prompt.show = function (field) {
    'use strict';
    game.current_points = parseInt(field.find('h3').text(), 10);
    game.current_questionID = field.attr("id");
    var column, row, dataset, question, answer;
    column = game.extractFromId(field.attr("id"), 1) - 1;
    row = game.extractFromId(field.attr("id"), 2) - 1;
    dataset = game.gamedata.data[column].data[row];

    $('#game').hide();

    if (dataset.hasOwnProperty("daily")) {
        if (game.points_bet) {
            game.current_points = parseInt(game.points_bet, 10);
            game.points_bet = null;
        } else {
            daily.show(field);
            return;
        }
    }

    question = prompt.loadImage(dataset.question);
    answer = prompt.loadImage(dataset.answer);

    $('#question').hide();
    $('#prompt').fadeIn(1000);
    $('#answer').html(question);
    $('#question').html(answer);
    if ($('#question').html().length === 0) {
        $('#correct-response').hide();
    } else {
        $('#correct-response').show();
    }
};

prompt.loadImage = function (image) {
    'use strict';
    var prefix = game.gamedata.directory;
    if (image.substring(0, 6) === "image:") {
        return "";
    }
    return image;
};

prompt.hide = function () {
    'use strict';
    $('#prompt').hide();
    $('#game').show();
};

prompt.showQuestion = function () {
    'use strict';
    $('#question').fadeIn(1000);
};

prompt.continueGame = function () {
    'use strict';
};

daily.show = function (field) {
    'use strict';
    $('#prompt').hide();
    $('#daily').show();

    $('#bet_submit').click(function () {
        game.points_bet = $("#bet").val();
        game.current_points = game.points_bet;
        prompt.show(field);
        $('#daily').hide();
    });
};

$(document).ready(function () {
    'use strict';
    $('tbody tr td').each(function () {
        $(this).addClass('cell')
            .click(function () {
                var field = $(this);
                if (!field.hasClass('dirty')) {
                    prompt.show(field);
                }
            });
    });

    $('textarea.edit').focus(function () {
        $(this).addClass('active');
        var val = $(this).val();
        if (val === "Enter Category" || val === "Enter Title") {
            this.select();
        }
    }).blur(function () {
        $(this).removeClass('active');
    }).autogrow();

    $('.clean').mouseover(function () {
        $(this).addClass('ie-hack');
    }).mouseout(function () {
        $(this).removeClass('ie-hack');
    });

    $('#fileinput').change(function () {
        game.loadFile(function (e) {
            var data, j;
            data = $.parseJSON(e.target.result);
            $('#title').html(data.name);
            $('#gametitle').html(data.name);
            j = 0;
            $('thead').find('th:not(#gametitle)').each(function () {
                var id, label;
                id = $(this).attr("id");
                label = data.data[j].name;
                $(this).html(label);
                j = j + 1;
            });
            game.gamedata = data;
        });
    });

    $("#add").click(function () {
        $("<input type=\"text\" name=\"team[]\" class=\"team\" />").appendTo("#teams");
    });
});
<|endoftext|>


<commit_before>'use strict';

define([
    'knockout', 'onefold-js', 'stringifyable', './application-event-dispatcher', 'text!ko-grid/data.html.template'
], function (ko, js, stringifyable, ApplicationEventDispatcher, dataTemplate) {
    var ELEMENT_NODE = window.Node.ELEMENT_NODE;

    var document = window.document;

    var data = {
        init: template => {
            template.into('body').insert(dataTemplate);
        },
        Constructor: function (bindingValue, config, grid) {
            var disposeCallbacks = [];

            /** @type {DataSource<?>} */
            this.source = bindingValue['dataSource'];

            this.valueSelector = bindingValue['valueSelector'] || config['valueSelector'] || js.functions.identity;
            this['valueSelector'] = this.valueSelector;
            this.observableValueSelector = bindingValue['observableValueSelector'] || config['observableValueSelector'] || this.valueSelector;
            this['observableValueSelector'] = this.observableValueSelector;

            this.predicates = ko.observableArray(bindingValue.filters || []);
            this['predicates'] = this.predicates;
            this.predicate = ko.pureComputed(() => stringifyable.predicates.and(this.predicates().map(ko.unwrap)));
            this['predicate'] = this.predicate;
            this.comparator = ko.observable(stringifyable.comparators.indifferent);
            this['comparator'] = this.comparator;
            this.offset = ko.observable(0);
            this['offset'] = this.offset;
            this.limit = ko.observable(Number.POSITIVE_INFINITY);
            this['limit'] = this.limit;

            this._preApplyBindings = js.functions.nop;
            this.__preApplyBindings = callback => {
                var innerCallback = this._preApplyBindings;
                this._preApplyBindings = () => {
                    callback(innerCallback);
                };
            };
            this._postApplyBindings = js.functions.nop;
            this.__postApplyBindings = callback => {
                var innerCallback = this._postApplyBindings;
                this._postApplyBindings = () => {
                    callback(innerCallback);
                };
            };

            disposeCallbacks.push(initTbodyElement.call(this, grid));
            disposeCallbacks.push(initRows.call(this));
            disposeCallbacks.push(initEventDispatching.call(this));
            disposeCallbacks.push(initElementLookup.call(this, grid));

            this._dispose = () => {
                disposeCallbacks.forEach(callback => {
                    callback();
                });
            };
        }
    };

    function initTbodyElement(grid) {
        this.__postApplyBindings(inner => {
            inner();
            this.__tbodyElement = grid.element.querySelector('.ko-grid-tbody');
        });

        return () => { this.__tbodyElement = null; };
    }

    function initRows() {
        var disposables = [];

        var rows = {};
        this.rows = rows;
        this['rows'] = rows;

        rows.displayed = ko.observableArray([]);
        rows['displayed'] = rows.displayed;

        rows.displayedSynchronized = ko.observable(false).extend({notify: 'always'});
        rows['displayedSynchronized'] = rows.displayedSynchronized;
        rows['__handleDisplayedRowsDeviate'] = () => { this.rows.displayedSynchronized(false); };
        rows['__handleDisplayedRowsSynchronized'] = () => { this.rows.displayedSynchronized(true); };

        this.__preApplyBindings(inner => {
            inner();

            var view = this.source.openView(q => q
                .filteredBy(this.predicate)
                .sortedBy(this.comparator)
                .offsetBy(this.offset)
                .limitedTo(this.limit));
            disposables.push(view);

            disposables.push(view.observables.subscribe(v => { this.rows.displayed(v); }));

            rows.displayed(view.observables());
        });

        var classifiers = [];
        rows['__classify'] = row => {
            var classes = classifiers.map(c => c(row));
            return Array.prototype.concat.apply([], classes);
        };
        rows.installClassifier = classifier => { classifiers.push(classifier); };
        rows['installClassifier'] = rows.installClassifier;

        return () => {
            disposables.forEach(disposable => {
                disposable.dispose();
            });
        };
    }

    function initEventDispatching() {
        var dispatchVia = dispatcher => {
            return event => {
                dispatcher.relativeToClosest('.ko-grid-cell').dispatch(event);
                return !event.defaultPrevented;
            };
        };

        var argumentsSupplier = (event, cellElement) => {
            var context = ko.contextFor(cellElement);
            var row = context['row']();
            var column = context['column']();
            var cell = row[column.property];

            return [event, cell, row, column];
        };

        var onMouseDownDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        var onClickDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        var onDoubleClickDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        var onContextMenuDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        this.onCellMouseDown = onMouseDownDispatcher.registerHandler.bind(onMouseDownDispatcher);
        this.onCellClick = onClickDispatcher.registerHandler.bind(onClickDispatcher);
        this.onCellDoubleClick = onDoubleClickDispatcher.registerHandler.bind(onDoubleClickDispatcher);
        this.onCellContextMenu = onContextMenuDispatcher.registerHandler.bind(onContextMenuDispatcher);
        this['onCellMouseDown '] = this.onCellMouseDown;
        this['onCellClick '] = this.onCellClick;
        this['onCellDoubleClick '] = this.onCellDoubleClick;
        this['onCellContextMenu '] = this.onCellContextMenu;

        this.__postApplyBindings(inner => {
            inner();
            this.__tbodyElement.addEventListener('mousedown', dispatchVia(onMouseDownDispatcher));
            this.__tbodyElement.addEventListener('click', dispatchVia(onClickDispatcher));
            this.__tbodyElement.addEventListener('dblclick', dispatchVia(onDoubleClickDispatcher));
            this.__tbodyElement.addEventListener('contextmenu', dispatchVia(onContextMenuDispatcher));
        });

        return js.functions.nop;
    }

    function initElementLookup(grid) {
        var nthRowElement = n => {
            var node = this.__tbodyElement.firstChild;
            var i = -1;
            while (node) {
                if (node.nodeType === ELEMENT_NODE && node.tagName === 'TR' && (' ' + node.className + ' ').indexOf('ko-grid-row') >= 0)
                    if (++i === n) return node;
                node = node.nextSibling;
            }
            throw new Error('Row `' + n + '` does not exist.');
        };

        var nthCellOfRow = (row, n) => {
            var node = row.firstChild;
            var i = -1;
            while (node) {
                if (node.nodeType === ELEMENT_NODE && node.tagName === 'TD' && (' ' + node.className + ' ').indexOf('td') >= 0)
                    if (++i === n) return node;
                node = node.nextSibling;
            }
            throw new Error('Column `' + n + '` does not exist.');
        };

        this.lookupCell = (row, column) => {
            var rowIndex = this.rows.displayed().indexOf(row);
            var columnIndex = grid.columns.displayed().indexOf(column);

            var element = nthCellOfRow(nthRowElement(rowIndex), columnIndex);

            function hijack(classes) {
                if (element.hasAttribute('data-hijacked'))
                    throw new Error('Illegal state: This cell is already hijacked.');

                while (element.firstChild)
                    ko.removeNode(element.firstChild);

                element.className += ' ' + classes;
                element.setAttribute('data-hijacked', 'hijacked ' + classes);

                function release() {
                    element.removeAttribute('data-hijacked');
                    while (element.firstChild)
                        ko.removeNode(element.firstChild);

                    var rowObservable = ko.contextFor(element)['row']();
                    if (column._initCell)
                        column._initCell(element, rowObservable, column);
                    else
                        element.appendChild(document.createTextNode(''));

                    updateCellElement(element, rowObservable(), column);
                }

                return {'dispose': release, 'release': release};
            }

            return {
                'element': element,
                'hijack': hijack
            };
        };
        this['lookupCell'] = this.lookupCell;

        return js.functions.nop;
    }

    ko.bindingHandlers['__gridRow'] = {
        'init': js.functions.nop,
        'update': (element, valueAccessor) => {
            var value = valueAccessor();
            var classify = value['classify'];
            var row = value['row']();
            var index = value['index']();

            var coreClasses = index % 2 === 1 ? ['ko-grid-tr', 'ko-grid-row', 'alternate'] : ['ko-grid-tr', 'ko-grid-row'];
            var additionalClasses = classify(row);
            var distinctClasses = coreClasses.concat(additionalClasses);
            element.className = distinctClasses.join(' ');
        }
    };

    ko.bindingHandlers['__gridCell'] = {
        'init': (element, valueAccessor) => {
            var value = valueAccessor();
            var row = value['row'];
            var column = value['column'];
            var columnValue = column();

            while (element.firstChild)
                ko.removeNode(element.firstChild);

            if (columnValue._initCell)
                columnValue._initCell(element, row, column);
            else
                element.appendChild(document.createTextNode(''));
            return {
                'controlsDescendantBindings': true
            };
        },
        'update': (element, valueAccessor) => {
            var value = valueAccessor();
            var row = value['row']();
            var column = value['column'].peek(); // can't change anyways => peek to keep dependency count low
            updateCellElement(element, row, column);
        }
    };

    function updateCellElement(element, row, column) {
        var cell = row[column.property];
        var cellValue = cell && ko.unwrap(cell);

        var hijacked = element.getAttribute('data-hijacked');

        // TODO since there may be thousands of cells we want to keep the dependency count at two (row+cell) => peek => need separate change handler for cellClasses
        var columnClasses = column.cellClasses.peek().join(' ');
        element.className = 'ko-grid-td ko-grid-cell ' + columnClasses + (hijacked ? ' ' + hijacked : '');

        if (hijacked) return;

        if (column._initCell)
            column._updateCell(element, cell, row, column);
        else {
            element.lastChild.nodeValue = column.renderValue(cellValue);
        }
    }

    return data;
});
<commit_msg>The body placeholder is no longer replaced.<commit_after>'use strict';

define([
    'knockout', 'onefold-js', 'stringifyable', './application-event-dispatcher', 'text!ko-grid/data.html.template'
], function (ko, js, stringifyable, ApplicationEventDispatcher, dataTemplate) {
    var ELEMENT_NODE = window.Node.ELEMENT_NODE;

    var document = window.document;

    var data = {
        init: template => {
            template.replace('body').with('body', dataTemplate);
        },
        Constructor: function (bindingValue, config, grid) {
            var disposeCallbacks = [];

            /** @type {DataSource<?>} */
            this.source = bindingValue['dataSource'];

            this.valueSelector = bindingValue['valueSelector'] || config['valueSelector'] || js.functions.identity;
            this['valueSelector'] = this.valueSelector;
            this.observableValueSelector = bindingValue['observableValueSelector'] || config['observableValueSelector'] || this.valueSelector;
            this['observableValueSelector'] = this.observableValueSelector;

            this.predicates = ko.observableArray(bindingValue.filters || []);
            this['predicates'] = this.predicates;
            this.predicate = ko.pureComputed(() => stringifyable.predicates.and(this.predicates().map(ko.unwrap)));
            this['predicate'] = this.predicate;
            this.comparator = ko.observable(stringifyable.comparators.indifferent);
            this['comparator'] = this.comparator;
            this.offset = ko.observable(0);
            this['offset'] = this.offset;
            this.limit = ko.observable(Number.POSITIVE_INFINITY);
            this['limit'] = this.limit;

            this._preApplyBindings = js.functions.nop;
            this.__preApplyBindings = callback => {
                var innerCallback = this._preApplyBindings;
                this._preApplyBindings = () => {
                    callback(innerCallback);
                };
            };
            this._postApplyBindings = js.functions.nop;
            this.__postApplyBindings = callback => {
                var innerCallback = this._postApplyBindings;
                this._postApplyBindings = () => {
                    callback(innerCallback);
                };
            };

            disposeCallbacks.push(initTbodyElement.call(this, grid));
            disposeCallbacks.push(initRows.call(this));
            disposeCallbacks.push(initEventDispatching.call(this));
            disposeCallbacks.push(initElementLookup.call(this, grid));

            this._dispose = () => {
                disposeCallbacks.forEach(callback => {
                    callback();
                });
            };
        }
    };

    function initTbodyElement(grid) {
        this.__postApplyBindings(inner => {
            inner();
            this.__tbodyElement = grid.element.querySelector('.ko-grid-tbody');
        });

        return () => { this.__tbodyElement = null; };
    }

    function initRows() {
        var disposables = [];

        var rows = {};
        this.rows = rows;
        this['rows'] = rows;

        rows.displayed = ko.observableArray([]);
        rows['displayed'] = rows.displayed;

        rows.displayedSynchronized = ko.observable(false).extend({notify: 'always'});
        rows['displayedSynchronized'] = rows.displayedSynchronized;
        rows['__handleDisplayedRowsDeviate'] = () => { this.rows.displayedSynchronized(false); };
        rows['__handleDisplayedRowsSynchronized'] = () => { this.rows.displayedSynchronized(true); };

        this.__preApplyBindings(inner => {
            inner();

            var view = this.source.openView(q => q
                .filteredBy(this.predicate)
                .sortedBy(this.comparator)
                .offsetBy(this.offset)
                .limitedTo(this.limit));
            disposables.push(view);

            disposables.push(view.observables.subscribe(v => { this.rows.displayed(v); }));

            rows.displayed(view.observables());
        });

        var classifiers = [];
        rows['__classify'] = row => {
            var classes = classifiers.map(c => c(row));
            return Array.prototype.concat.apply([], classes);
        };
        rows.installClassifier = classifier => { classifiers.push(classifier); };
        rows['installClassifier'] = rows.installClassifier;

        return () => {
            disposables.forEach(disposable => {
                disposable.dispose();
            });
        };
    }

    function initEventDispatching() {
        var dispatchVia = dispatcher => {
            return event => {
                dispatcher.relativeToClosest('.ko-grid-cell').dispatch(event);
                return !event.defaultPrevented;
            };
        };

        var argumentsSupplier = (event, cellElement) => {
            var context = ko.contextFor(cellElement);
            var row = context['row']();
            var column = context['column']();
            var cell = row[column.property];

            return [event, cell, row, column];
        };

        var onMouseDownDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        var onClickDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        var onDoubleClickDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        var onContextMenuDispatcher = new ApplicationEventDispatcher(argumentsSupplier);
        this.onCellMouseDown = onMouseDownDispatcher.registerHandler.bind(onMouseDownDispatcher);
        this.onCellClick = onClickDispatcher.registerHandler.bind(onClickDispatcher);
        this.onCellDoubleClick = onDoubleClickDispatcher.registerHandler.bind(onDoubleClickDispatcher);
        this.onCellContextMenu = onContextMenuDispatcher.registerHandler.bind(onContextMenuDispatcher);
        this['onCellMouseDown '] = this.onCellMouseDown;
        this['onCellClick '] = this.onCellClick;
        this['onCellDoubleClick '] = this.onCellDoubleClick;
        this['onCellContextMenu '] = this.onCellContextMenu;

        this.__postApplyBindings(inner => {
            inner();
            this.__tbodyElement.addEventListener('mousedown', dispatchVia(onMouseDownDispatcher));
            this.__tbodyElement.addEventListener('click', dispatchVia(onClickDispatcher));
            this.__tbodyElement.addEventListener('dblclick', dispatchVia(onDoubleClickDispatcher));
            this.__tbodyElement.addEventListener('contextmenu', dispatchVia(onContextMenuDispatcher));
        });

        return js.functions.nop;
    }

    function initElementLookup(grid) {
        var nthRowElement = n => {
            var node = this.__tbodyElement.firstChild;
            var i = -1;
            while (node) {
                if (node.nodeType === ELEMENT_NODE && node.tagName === 'TR' && (' ' + node.className + ' ').indexOf('ko-grid-row') >= 0)
                    if (++i === n) return node;
                node = node.nextSibling;
            }
            throw new Error('Row `' + n + '` does not exist.');
        };

        var nthCellOfRow = (row, n) => {
            var node = row.firstChild;
            var i = -1;
            while (node) {
                if (node.nodeType === ELEMENT_NODE && node.tagName === 'TD' && (' ' + node.className + ' ').indexOf('td') >= 0)
                    if (++i === n) return node;
                node = node.nextSibling;
            }
            throw new Error('Column `' + n + '` does not exist.');
        };

        this.lookupCell = (row, column) => {
            var rowIndex = this.rows.displayed().indexOf(row);
            var columnIndex = grid.columns.displayed().indexOf(column);

            var element = nthCellOfRow(nthRowElement(rowIndex), columnIndex);

            function hijack(classes) {
                if (element.hasAttribute('data-hijacked'))
                    throw new Error('Illegal state: This cell is already hijacked.');

                while (element.firstChild)
                    ko.removeNode(element.firstChild);

                element.className += ' ' + classes;
                element.setAttribute('data-hijacked', 'hijacked ' + classes);

                function release() {
                    element.removeAttribute('data-hijacked');
                    while (element.firstChild)
                        ko.removeNode(element.firstChild);

                    var rowObservable = ko.contextFor(element)['row']();
                    if (column._initCell)
                        column._initCell(element, rowObservable, column);
                    else
                        element.appendChild(document.createTextNode(''));

                    updateCellElement(element, rowObservable(), column);
                }

                return {'dispose': release, 'release': release};
            }

            return {
                'element': element,
                'hijack': hijack
            };
        };
        this['lookupCell'] = this.lookupCell;

        return js.functions.nop;
    }

    ko.bindingHandlers['__gridRow'] = {
        'init': js.functions.nop,
        'update': (element, valueAccessor) => {
            var value = valueAccessor();
            var classify = value['classify'];
            var row = value['row']();
            var index = value['index']();

            var coreClasses = index % 2 === 1 ? ['ko-grid-tr', 'ko-grid-row', 'alternate'] : ['ko-grid-tr', 'ko-grid-row'];
            var additionalClasses = classify(row);
            var distinctClasses = coreClasses.concat(additionalClasses);
            element.className = distinctClasses.join(' ');
        }
    };

    ko.bindingHandlers['__gridCell'] = {
        'init': (element, valueAccessor) => {
            var value = valueAccessor();
            var row = value['row'];
            var column = value['column'];
            var columnValue = column();

            while (element.firstChild)
                ko.removeNode(element.firstChild);

            if (columnValue._initCell)
                columnValue._initCell(element, row, column);
            else
                element.appendChild(document.createTextNode(''));
            return {
                'controlsDescendantBindings': true
            };
        },
        'update': (element, valueAccessor) => {
            var value = valueAccessor();
            var row = value['row']();
            var column = value['column'].peek(); // can't change anyways => peek to keep dependency count low
            updateCellElement(element, row, column);
        }
    };

    function updateCellElement(element, row, column) {
        var cell = row[column.property];
        var cellValue = cell && ko.unwrap(cell);

        var hijacked = element.getAttribute('data-hijacked');

        // TODO since there may be thousands of cells we want to keep the dependency count at two (row+cell) => peek => need separate change handler for cellClasses
        var columnClasses = column.cellClasses.peek().join(' ');
        element.className = 'ko-grid-td ko-grid-cell ' + columnClasses + (hijacked ? ' ' + hijacked : '');

        if (hijacked) return;

        if (column._initCell)
            column._updateCell(element, cell, row, column);
        else {
            element.lastChild.nodeValue = column.renderValue(cellValue);
        }
    }

    return data;
});
<|endoftext|>


<commit_before>var transpile = require('transpile');
var nodeDependencyMap = require("../node/dependency_map"),
	minify = require("../buildTypes/minifyJS"),
	transformActiveSource = require("../node/transform_active_source"),
	_ = require("lodash");

var transpileNode = function(node, outputFormat, options){
	if( !node.load.metadata.buildType || node.load.metadata.buildType === "js"  ) {

		transformActiveSource(node,"format-"+outputFormat,function(node, source){
			if(options.useNormalizedDependencies) {
				options.normalizeMap = nodeDependencyMap(node);
			}
			// make sure load has activeSource
			var load = _.clone(node.load, true);
			load.source = source || load.source;
			// Minify globals prior to transpiling because they can't
			// be minified after they become a System.define.
			if(load.metadata.format === "global" && options.minify) {
				load.source = minify(load.source);
			}
			return transpile.to(load, outputFormat, options);
		});
	}
};

module.exports = function(graph, outputFormat, options){

	options = options || {};
	if(Array.isArray(graph)) {
		graph.forEach(function(node){
			transpileNode(node, outputFormat, options);
		});
	} else {
		for(var name in graph) {
			var node = graph[name];
			// If JavaScript
			transpileNode(node, outputFormat, options);
		}
	}
};
<commit_msg>Pass options object to minifyJS in transpile module.<commit_after>var transpile = require('transpile');
var nodeDependencyMap = require("../node/dependency_map"),
	minify = require("../buildTypes/minifyJS"),
	transformActiveSource = require("../node/transform_active_source"),
	_ = require("lodash");

var transpileNode = function(node, outputFormat, options){
	if( !node.load.metadata.buildType || node.load.metadata.buildType === "js"  ) {

		transformActiveSource(node,"format-"+outputFormat,function(node, source){
			if(options.useNormalizedDependencies) {
				options.normalizeMap = nodeDependencyMap(node);
			}
			// make sure load has activeSource
			var load = _.clone(node.load, true);
			load.source = source || load.source;
			// Minify globals prior to transpiling because they can't
			// be minified after they become a System.define.
			if(load.metadata.format === "global" && options.minify) {
				load.source = minify(load.source, options);
			}
			return transpile.to(load, outputFormat, options);
		});
	}
};

module.exports = function(graph, outputFormat, options){

	options = options || {};
	if(Array.isArray(graph)) {
		graph.forEach(function(node){
			transpileNode(node, outputFormat, options);
		});
	} else {
		for(var name in graph) {
			var node = graph[name];
			// If JavaScript
			transpileNode(node, outputFormat, options);
		}
	}
};
<|endoftext|>


<commit_before>elation.require(['janusweb.janusbase'], function() {
  elation.component.add('engine.things.januslight', function() {
    this.postinit = function() {
      elation.engine.things.januslight.extendclass.postinit.call(this);
      this.defineProperties({
        light_directional: { type: 'bool', default: false, set: this.updateLight },
        light_range: { type: 'float', default: 10, set: this.updateLight },
        light_intensity: { type: 'float', default: 100, set: this.updateLight },
        light_cone_angle: { type: 'float', default: 0, set: this.updateLight },
        light_cone_exponent: { type: 'float', default: 1, set: this.updateLight },
        light_shadow: { type: 'boolean', default: false, set: this.updateLight },
        light_shadow_near: { type: 'float', default: .1, set: this.updateLight },
        light_shadow_far: { type: 'float', set: this.updateLight },
        light_shadow_bias: { type: 'float', default: .02, set: this.updateLight },
        light_shadow_radius: { type: 'float', default: 2.5, set: this.updateLight },
      });
    }
    this.createObject3D = function() {
      var obj = new THREE.Object3D();
      if (this.light_directional) {
        this.light = new THREE.DirectionalLight(this.properties.color, this.light_intensity);
        obj.add(this.light);
      } else if (this.light_cone_angle == 0) {
        this.light = new THREE.PointLight(this.properties.color, 1, this.light_range);
        this.light.position.set(0,0,0);
        obj.add(this.light);
      } else if (this.light_cone_angle > 0) {
        var angle = Math.acos(this.light_cone_angle);
        this.light = new THREE.SpotLight(this.properties.color, 1, this.light_range, angle);
        //this.light.position.set(0,0,0);
        obj.add(this.light);
      }
      this.updateLight();
      return obj;
    }
    this.updateColor = function() {
      this.updateLight();
    }
    this.createChildren = function() {
      // TODO - should be an easy way of toggling helpers
      /*
      var scene = this.objects['3d'];
      while (scene.parent) {
        scene = scene.parent;
      }

      if (this.light_cone_angle == 0) {
        var helper = new THREE.PointLightHelper(this.light);
        scene.add(helper);
      } else {
        var helper = new THREE.SpotLightHelper(this.light);
        scene.add(helper);
      }
      */
    }
    this.physics_update = function() {
      this.localToWorld(this.light.target.position.set(0,0,-1));
      this.light.target.updateMatrixWorld();
    }
    this.updateLight = function() {
      if (this.light) {
        //this.light.intensity = this.light_intensity / 100;
        var avgscale = (this.scale.x + this.scale.y + this.scale.z) / 3;
        this.light.intensity = this.light_intensity / 100;
        this.light.color.copy(this.color);
        this.light.color.multiplyScalar(this.light_intensity * avgscale * avgscale);
        this.light.distance = this.light_range * avgscale;
        this.updateShadowmap();
      }
    }
    this.updateShadowmap = function() {
      var player = this.engine.client.player;
      var shadowSize = player.getSetting('render.shadows.size', elation.config.get('janusweb.materials.shadows.size', 512));

      this.light.castShadow = this.light_shadow;
      this.light.shadow.radius = this.light_shadow_radius;
      this.light.shadow.camera.near = elation.utils.any(this.light_shadow_near, 0.1);
      this.light.shadow.camera.far = elation.utils.any(this.light_shadow_far, this.light_range);
      this.light.shadow.camera.fov = 90;
      this.light.shadow.mapSize.set(shadowSize, shadowSize);
      this.light.shadow.bias = this.light_shadow_bias;
    }
    this.getProxyObject = function(classdef) {
      var proxy = elation.engine.things.janusobject.extendclass.getProxyObject.call(this, classdef);
      proxy._proxydefs = {
        light_range:         [ 'property', 'light_range'],
        light_intensity:     [ 'property', 'light_intensity'],
        light_cone_angle:    [ 'property', 'light_cone_angle'],
        light_cone_exponent: [ 'property', 'light_cone_exponent'],
        light_shadow:        [ 'property', 'light_shadow'],
        light_shadow_near:   [ 'property', 'light_shadow_near'],
        light_shadow_far:    [ 'property', 'light_shadow_far'],
        light_shadow_bias:   [ 'property', 'light_shadow_bias'],
        light_shadow_radius: [ 'property', 'light_shadow_radius'],
      };
      return proxy;
    }
  }, elation.engine.things.janusbase);
});
<commit_msg>Changed default shadow bias<commit_after>elation.require(['janusweb.janusbase'], function() {
  elation.component.add('engine.things.januslight', function() {
    this.postinit = function() {
      elation.engine.things.januslight.extendclass.postinit.call(this);
      this.defineProperties({
        light_directional: { type: 'bool', default: false, set: this.updateLight },
        light_range: { type: 'float', default: 10, set: this.updateLight },
        light_intensity: { type: 'float', default: 100, set: this.updateLight },
        light_cone_angle: { type: 'float', default: 0, set: this.updateLight },
        light_cone_exponent: { type: 'float', default: 1, set: this.updateLight },
        light_shadow: { type: 'boolean', default: false, set: this.updateLight },
        light_shadow_near: { type: 'float', default: .1, set: this.updateLight },
        light_shadow_far: { type: 'float', set: this.updateLight },
        light_shadow_bias: { type: 'float', default: .0001, set: this.updateLight },
        light_shadow_radius: { type: 'float', default: 2.5, set: this.updateLight },
      });
    }
    this.createObject3D = function() {
      var obj = new THREE.Object3D();
      if (this.light_directional) {
        this.light = new THREE.DirectionalLight(this.properties.color, this.light_intensity);
        obj.add(this.light);
      } else if (this.light_cone_angle == 0) {
        this.light = new THREE.PointLight(this.properties.color, 1, this.light_range);
        this.light.position.set(0,0,0);
        obj.add(this.light);
      } else if (this.light_cone_angle > 0) {
        var angle = Math.acos(this.light_cone_angle);
        this.light = new THREE.SpotLight(this.properties.color, 1, this.light_range, angle);
        //this.light.position.set(0,0,0);
        obj.add(this.light);
      }
      this.updateLight();
      return obj;
    }
    this.updateColor = function() {
      this.updateLight();
    }
    this.createChildren = function() {
      // TODO - should be an easy way of toggling helpers
      /*
      var scene = this.objects['3d'];
      while (scene.parent) {
        scene = scene.parent;
      }

      if (this.light_cone_angle == 0) {
        var helper = new THREE.PointLightHelper(this.light);
        scene.add(helper);
      } else {
        var helper = new THREE.SpotLightHelper(this.light);
        scene.add(helper);
      }
      */
    }
    this.physics_update = function() {
      this.localToWorld(this.light.target.position.set(0,0,-1));
      this.light.target.updateMatrixWorld();
    }
    this.updateLight = function() {
      if (this.light) {
        //this.light.intensity = this.light_intensity / 100;
        var avgscale = (this.scale.x + this.scale.y + this.scale.z) / 3;
        this.light.intensity = this.light_intensity / 100;
        this.light.color.copy(this.color);
        this.light.color.multiplyScalar(this.light_intensity * avgscale * avgscale);
        this.light.distance = this.light_range * avgscale;
        this.updateShadowmap();
      }
    }
    this.updateShadowmap = function() {
      var player = this.engine.client.player;
      var shadowSize = player.getSetting('render.shadows.size', elation.config.get('janusweb.materials.shadows.size', 512));

      this.light.castShadow = this.light_shadow;
      this.light.shadow.radius = this.light_shadow_radius;
      this.light.shadow.camera.near = elation.utils.any(this.light_shadow_near, 0.1);
      this.light.shadow.camera.far = elation.utils.any(this.light_shadow_far, this.light_range);
      this.light.shadow.camera.fov = 90;
      this.light.shadow.mapSize.set(shadowSize, shadowSize);
      this.light.shadow.bias = this.light_shadow_bias;
    }
    this.getProxyObject = function(classdef) {
      var proxy = elation.engine.things.janusobject.extendclass.getProxyObject.call(this, classdef);
      proxy._proxydefs = {
        light_range:         [ 'property', 'light_range'],
        light_intensity:     [ 'property', 'light_intensity'],
        light_cone_angle:    [ 'property', 'light_cone_angle'],
        light_cone_exponent: [ 'property', 'light_cone_exponent'],
        light_shadow:        [ 'property', 'light_shadow'],
        light_shadow_near:   [ 'property', 'light_shadow_near'],
        light_shadow_far:    [ 'property', 'light_shadow_far'],
        light_shadow_bias:   [ 'property', 'light_shadow_bias'],
        light_shadow_radius: [ 'property', 'light_shadow_radius'],
      };
      return proxy;
    }
  }, elation.engine.things.janusbase);
});
<|endoftext|>


<commit_before>/* ****************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Steven Jimenez
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 * ***************************************************************************/

jspyder.extend.fn("form", function () {
    var js = this;

    /**
     * @class jspyder.form
     * @member jspyder
     *
     * Initializes a JSpyder Form object.
     *
     * @param {Object} [config]
     *      Configuration flags for building the forms element.
     *
     * @param {Function} [config.success]
     *     Function to trigger on form submission, if the validation
     *     checks pass.  This can be overridden, later.  Expected
     *     parameters are:
     *
     * @param {Object} [config.success.values]
     *     The values of each field in the form, where keys correspond
     *     to field names and values correspond to their values.
     *
     * @param {Function} [config.failure]
     *     Function to trigger on form submission failure. For example,
     *     if the validation checks failed.  This can be overridden,
     *     later.
     *
     * @param {Object} [config.failure.values]
     *     The values of each field in the form, where keys correspond
     *     to field names and values correspond to their values.
     *
     * @param {Object} [config.failure.invalid]
     *     The values of each invalid field in the form, where keys
     *     correspond to field names and values correspond to their
     *     values.
     *
     * @param {Function} [config.reset]
     *     Function to trigger on form rest.  This can be overridden,
     *     later.
     *
     * @return {Object}
     *      JSpyder Function object.
     */
    function js_form(config, fn) {
        var form = Object.create(js_form.fn, {
            _dom: { value: js.dom("<form></form>") },
            _template: { value: {} }
        });

        // load in the configuration options
        if (config) {
            // success function
            if (config.success) { form._success = config.success; }
            // failure function
            if (config.failure) { form._failure = config.failure; }
            // reset function
            if (config.reset) { form._reset = config.reset; }
            // form elements
            if (config.elements) {
                form.addFields(config.elements);
            }
        }

        if (typeof fn === "function") {
            fn.apply(this);
        }

        return form;
    }

    js_form.fn = {
        // private:
        /**
         * @private
         * @method
         *
         * Callback function which will execute if the form submits
         * successfully.
         *
         * @param {Object} values
         *      An object where keys correspond to input names, and values
         *      correspond to the values they are storing.
         */
        _submit: function (values, invalid) { return this; },

        /**
         * @private
         * @method
         *
         * Callback function which will execute if the form fails to submit
         * successfully (e.g. failed the validation check).
         *
         * @param {Object} values
         *      An object where keys correspond to input names, and values
         *      correspond to the values they are storing.
         *
         * @param {Object} invalid
         *      An object of invalid fields where keys correspond to input
         *      names, and values correspond to the values they are storing.
         */
        _failed: function (values, invalid) { return this; },

        /**
         * @private
         * @method
         *
         * Callback function which will execute if the reset event is received.
         */
        _reset: function () { return this; },

        /**
         * @private
         * @property {Object}
         *
         * jspyder.dom object pointing to the created form element.
         */
        _dom: null,

        /**
         * @private
         * @property {Object}
         *
         * List of elements that the form is dealing with, to prevent having to
         * deal directly with making calls to the DOM.
         */
        _fields: null,

        /**
         * @method
         * Adds a group of fields using jspyder.form.addField
         */

        addFields: function(fields) {
            js.alg.each(fields, this._addFields, { self: this });
            return this;
        },

        _addFields: function(field, name, fields, context) {
            context.self.addField(name, field);
            return;
        },

        /**
         * @method
         *
         * Adds a new field to the form, if the name does not already exist,
         * using the name provided.
         *
         * @param {String} name
         *      The name which will be used to refer to the generated field.
         *
         * @param {Object} [config]
         *      The configuration options which will be used to generate and
         *      style the created field.
         *
         * @param {String} [config.type]
         *      The type of field which should be created:
         *      - **input** *default*: standard input field without
         *          any special attributes or constraints.
         *      - **checkbox**: A set of checkboxes will be created.  Each value
         *          should be designated with label-value pairs stored in an
         *          array (see below).
         *      - **dropdown**: A dropdown control will be created.  Each value
         *          should be designated with label-value pairs stored in an
         *          array (see below).
         *      - **textarea**: A standard multi-line text field.
         *      - **hidden**: An abstract field which is not rendered to the
         *          page, but in all other ways behaves like a standard *input*
         *          field.
         *
         * @param {Object[]} [config.values]
         *      A list of text-value pairs.
         *
         * @param {String} [config.values.label]
         *      The label to display in place of the value.  If this is omitted,
         *      and a value is provided, then this will default to the value.
         *
         * @param {String} [config.values.value]
         *      The value for this particular option.  If this is omitted, and
         *      a label is provided, then this will default to the label.
         */
        addField: function (name, config) {
            var $field = js.dom(),
                cfg = Object.create(js_form.fn.fieldTemplate);

            // copy all of the config options over, if they exist.
            js.alg.mergeObj(cfg, config);
            if (config.values) { cfg.values = js.alg.sliceArray(config.values); }

            switch (cfg.type) {
                case "checkbox":
                    js.alg.each(cfg.values, this._createCheckboxes, { $field: $field, cfg: cfg, name: name });
                    break;

                case "textarea":
                    $field.and("<textarea name=\"" + name + "\" >");
                    break;

                case "dropdown":
                case "hidden":
                case "input":
                default:
                    $field.and("<input name=\"" + name + "\"></input>");

                    if (cfg.type === "hidden") {
                        $field.setCss({ "display": "none !important" });
                    }

                    if (cfg.type === "dropdown") {
                        // do dropdown stuff
                    }

                    if (cfg.type === "autocomplete") {
                        // do autocomplete stuff (similar to dropdown)
                    }

                    break;
            }

            if (!this._fields) {
                this._fields = {};
            }
            this._fields[name] = { type: cfg.type, field: $field };

            return this;
        },

        /**
         * @private
         * @method
         *
         * Constructor for creating a series of checkbox elements.  These are
         * added sequentially.
         *
         * @param {Object} option
         * @param {String} [option.text] Label for checkbox element
         * @param {String} [option.value] Value to set for the checkbox element
         * @param {Number} index The ID number for the current option
         * @param {Object[]} options Array of options being iterated
         * @param {Object} context
         * @param {String} context.name The name these fields will be stored under.
         * @param {Object} context.$field JSpyder DOM the checkboxes are being added to.
         */
        _createCheckboxes: function (option, index, options, context) {
            var $field = context.$field,
                name = context.name;

            $field.and(
                "<input value=\"" + (option.value || option.text) +
                "\" name=\"" + name + "\" type=\"checkbox\" />" +
                "<label>" + (option.text || option.value) + "</label>");
        },

        /**
         * @method
         *
         * Retrieves the values of all of the elements in the JS-Form.
         *
         * @param {Function} fn
         *      A callback function to execute after the values have been
         *      calculated.  The context points back to the js-form.
         * @param {Object} fn.values
         *      The values of all of the form elements are pushed into the
         *      first parameter of the function fn.
         */
        values: function (fn) {
            var values = {};
            js.alg.each(this._fields, this._values, { self: this, values: values });
            fn.apply(this, [values]);
            return this;
        },

        /**
         * @private
         * @method
         *
         * Logical loop for jspyder.form.values; separated from the main
         * function for efficient memory-management.
         *
         * @param {Object} fieldSet
         *      A pair of values being pushed in from jspyder.form._fields
         *
         * @param {String} fieldSet.type
         *      The type of element being created.
         *
         * @param {Object} fieldSet.field
         *      A reference to the JS-DOM object containing the form fields.
         *
         * @param {String} name
         *      The name of the current field in the iterator.
         *
         * @param {Object} fields
         *      Reference to jspyder.form._fields
         *
         * @param {Object} context
         * @param {Object} context.values
         *      Reference to the field values which are being returned by
         *      jspyder.form.values
         *
         * @param {Object} context.self
         *      JS-Form
         */
        _values: function (fieldSet, name, fields, context) {
            var self = context.self,
                values = context.values,
                $field = fieldSet.field,
                $type = fieldSet.type;

            values[name] = null;

            switch ($type) {
                case "checkbox":
                    values[name] = self._checkboxValue($field);
                    break;
                default:
                    values[name] = self._genericValue($field);
                    break;
            }

            return;
        },

        /**
         * @method
         * @private
         *
         * Uses a generic value-retrieval method; this should be sufficient for
         * most single-value controls (e.g. not checkboxes)
         *
         * @param {Object} $input
         *      JS-DOM object to retrieve a value from.
         *
         * @return {String}
         *      The value of the element.
         */
        _genericValue: function ($input) {
            var value = "";

            if ($input) {
                $input.element(0, function () {
                    value = this.value;
                    if (typeof value === "undefined" || value === null) {
                        value = "";
                    }
                });
            }

            return value;
        },

        /**
         * @method
         * @private
         *
         * Specialized value retrieval for checkbox elements.
         */
        _checkboxValue: function ($checkboxes) {
            var value = [];

            if ($checkboxes) {
                $checkboxes.each(function (checkbox) {
                    if ((checkbox instanceof HTMLInputElement)
                        && (checkbox.getAttribute("type") === "checkbox")
                        && (checkbox.checked)) {
                        value.push(checkbox.value);
                    }
                });
            }

            return value;
        },

        fieldTemplate: {
            type: "input",
            values: [],
        },

        /**
         * @method
         *
         * Triggers a manual form submission.  If the form fails validation, or
         * any other errors occur, then the failed callback is executed.
         * Otherwise, the success function is executed.
         *
         * @param {Function} [onSuccess]
         *      Overrides the success function provided in the configuration on
         *      construction.  See jspyder.form constructor for expected
         *      parameters.
         *
         * @param {Function} [onFail]
         *      Overrides the failure function provided in the configuration on
         *      construction.  See jspyder.form constructor for expected
         *      parameters.
         */
        submit: function(onSuccess, onFail) {
            return this;
        },

        /**
         * @method
         *
         * Triggers a manual form reset.  This will turn all of the form fields
         * back to their initial values on creation.
         *
         * @param {Function} [fn]
         *      Optional callback to execute after the reset has been completed.
         *      See jspyder.form constructor for expected parameters.
         */
        reset: function(fn) {
            return this;
        },

        /**
         * @method
         *
         * Triggers a manual form reset.  This will turn all of the form fields
         * back to their initial values on creation.
         *
         * @param {Function} [fn]
         *      Optional callback to execute after the validation has been
         *      completed.  See jspyder.form constructor for expected
         *      parameters.
         */
        validate: function(fn) {
            return this;
        },

        /**
         * @method
         * Exports the jspyder.dom element.
         *
         * @param {Function} [fn]
         *      Optional callback function to execute, using the form js.dom
         *      element as the context and the js.form object as the first
         *      parameter.
         *
         * @param {Mixed} [data]
         *      Optional parameter to pass in as a second parameter for [fn].
         *
         * @return {Object} js.dom object.
         */
        export: function(fn, data) {
            if(typeof fn === "function") {
                fn.apply(this._dom, [this, data]);
            }
            return this._dom;
        },
    };

    return js_form;
 });<commit_msg>Weekend Changes<commit_after>/* ****************************************************************************
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 Steven Jimenez
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 * ***************************************************************************/

jspyder.extend.fn("form", function () {
    var js = this;

    /**
     * @class jspyder.form
     * @member jspyder
     *
     * Initializes a JSpyder Form object.
     *
     * @param {Object} [config]
     *      Configuration flags for building the forms element.
     *
     * @param {Function} [config.success]
     *     Function to trigger on form submission, if the validation
     *     checks pass.  This can be overridden, later.  Expected
     *     parameters are:
     *
     * @param {Object} [config.success.values]
     *     The values of each field in the form, where keys correspond
     *     to field names and values correspond to their values.
     *
     * @param {Function} [config.failure]
     *     Function to trigger on form submission failure. For example,
     *     if the validation checks failed.  This can be overridden,
     *     later.
     *
     * @param {Object} [config.failure.values]
     *     The values of each field in the form, where keys correspond
     *     to field names and values correspond to their values.
     *
     * @param {Object} [config.failure.invalid]
     *     The values of each invalid field in the form, where keys
     *     correspond to field names and values correspond to their
     *     values.
     *
     * @param {Function} [config.reset]
     *     Function to trigger on form rest.  This can be overridden,
     *     later.
     *
     * @return {Object}
     *      JSpyder Function object.
     */
    function js_form(config, fn) {
        var form = Object.create(js_form.fn, {
            _dom: { value: js.dom("<form></form>") },
            _template: { value: {} }
        });

        // load in the configuration options
        if (config) {
            // success function
            if (config.success) { form._success = config.success; }
            // failure function
            if (config.failure) { form._failure = config.failure; }
            // reset function
            if (config.reset) { form._reset = config.reset; }
            // form elements
            if (config.elements) {
                form.addFields(config.elements);
            }
        }

        if (typeof fn === "function") {
            fn.apply(this);
        }

        return form;
    }

    js_form.fn = {
        /**
         * @private
         * @method
         *
         * Callback function which will execute if the form submits
         * successfully.
         *
         * @param {Object} values
         *      An object where keys correspond to input names, and values
         *      correspond to the values they are storing.
         */
        _submit: function (values, invalid) { return this; },

        /**
         * @private
         * @method
         *
         * Callback function which will execute if the form fails to submit
         * successfully (e.g. failed the validation check).
         *
         * @param {Object} values
         *      An object where keys correspond to input names, and values
         *      correspond to the values they are storing.
         *
         * @param {Object} invalid
         *      An object of invalid fields where keys correspond to input
         *      names, and values correspond to the values they are storing.
         */
        _failed: function (values, invalid) { return this; },

        /**
         * @private
         * @method
         *
         * Callback function which will execute if the reset event is received.
         */
        _reset: function () { return this; },

        /**
         * @private
         * @property {Object}
         *
         * jspyder.dom object pointing to the created form element.
         */
        _dom: null,

        /**
         * @private
         * @property {Object}
         *
         * List of elements that the form is dealing with, to prevent having to
         * deal directly with making calls to the DOM.
         */
        _fields: null,

        /**
         * @method
         * Adds a group of fields using jspyder.form.addField where keys
         * correspond to field names and values correspond to field templates.
         *
         * @param {Object} fields
         */

        addFields: function(fields) {
            for (var name in fields) {
                this.addField(name, fields[name])
            }
            return this;
        },

        /**
         * @method
         *
         * Adds a new field to the form, if the name does not already exist,
         * using the name provided.
         *
         * @param {String} name
         *      The name which will be used to refer to the generated field.
         *
         * @param {Object} [config]
         *      The configuration options which will be used to generate and
         *      style the created field.
         *
         * @param {String} [config.type]
         *      The type of field which should be created:
         *      - **input** *default*: standard input field without
         *          any special attributes or constraints.
         *      - **checkbox**: A set of checkboxes will be created.  Each value
         *          should be designated with label-value pairs stored in an
         *          array (see below).
         *      - **dropdown**: A dropdown control will be created.  Each value
         *          should be designated with label-value pairs stored in an
         *          array (see below).
         *      - **textarea**: A standard multi-line text field.
         *      - **hidden**: An abstract field which is not rendered to the
         *          page, but in all other ways behaves like a standard *input*
         *          field.
         *
         * @param {Object[]} [config.values]
         *      A list of text-value pairs.
         *
         * @param {String} [config.values.label]
         *      The label to display in place of the value.  If this is omitted,
         *      and a value is provided, then this will default to the value.
         *
         * @param {String} [config.values.value]
         *      The value for this particular option.  If this is omitted, and
         *      a label is provided, then this will default to the label.
         *
         * @param {String} [config.section]
         *      The name of a section to add this particular field to.  If
         *      blank, then this field is not added directly to the list.
         */
        addField: function (name, config) {
            var $field = js.dom(),
                cfg = Object.create(js_form.fn.fieldTemplate),
                option, i;

            // copy all of the config options over, if they exist.
            js.alg.mergeObj(cfg, config);
            if (config.values) { cfg.values = js.alg.sliceArray(config.values); }

            switch (cfg.type) {
                // case "section":
                //     break;

                case "checkbox":
                    // js.alg.each(cfg.values, this._createCheckboxes, { $field: $field, cfg: cfg, name: name });
                    for (i = 0; i < config.values.length; i++) {
                        option = config.values[i];
                        $field.and(
                            "<input value=\"" + (option.value || option.text) +
                            "\" name=\"" + name + "\" type=\"checkbox\" />" +
                            "<label>" + (option.text || option.value) + "</label>");
                    }
                    break;

                case "textarea":
                    $field.and("<textarea name=\"" + name + "\" >");
                    break;

                case "dropdown":
                case "hidden":
                case "input":
                default:
                    $field.and("<input name=\"" + name + "\"></input>");

                    if (cfg.type === "hidden") {
                        $field.setCss({ "display": "none !important" });
                    }

                    if (cfg.type === "dropdown") {
                        // do dropdown stuff
                    }

                    if (cfg.type === "autocomplete") {
                        // do autocomplete stuff (similar to dropdown)
                    }

                    break;
            }

            if (!this._fields) {
                this._fields = {};
            }
            this._fields[name] = { type: cfg.type, field: $field, section: config.section || null };

            return this;
        },

        /**
         * @private
         * @method
         *
         * Constructor for creating a series of checkbox elements.  These are
         * added sequentially.
         *
         * @param {Object} option
         * @param {String} [option.text] Label for checkbox element
         * @param {String} [option.value] Value to set for the checkbox element
         * @param {Number} index The ID number for the current option
         * @param {Object[]} options Array of options being iterated
         * @param {Object} context
         * @param {String} context.name The name these fields will be stored under.
         * @param {Object} context.$field JSpyder DOM the checkboxes are being added to.
         */
        // _createCheckboxes: function (option, index, options, context) {
        //     var $field = context.$field,
        //         name = context.name;

        //     $field.and(
        //         "<input value=\"" + (option.value || option.text) +
        //         "\" name=\"" + name + "\" type=\"checkbox\" />" +
        //         "<label>" + (option.text || option.value) + "</label>");
        // },

        /**
         * @method
         *
         * Retrieves the values of all of the elements in the JS-Form.
         *
         * @param {Function} fn
         *      A callback function to execute after the values have been
         *      calculated.  The context points back to the js-form.
         * @param {Object} fn.values
         *      The values of all of the form elements are pushed into the
         *      first parameter of the function fn.
         */
        values: function (fn) {
            var values = {};
            // js.alg.each(this._fields, this._values, { self: this, values: values });

            var $field, $type, name;
            for (name in this._fields) {
                $field = this._fields[name].field;
                $type = this._fields[name].type;
                values[name] = null;

                switch ($type) {
                    case "checkbox":
                        values[name] = self._checkboxValue($field);
                        break;
                    default:
                        values[name] = self._genericValue($field);
                        break;
                }
            }

            fn.apply(this, [values]);
            return this;
        },

        /**
         * @private
         * @method
         *
         * Logical loop for jspyder.form.values; separated from the main
         * function for efficient memory-management.
         *
         * @param {Object} fieldSet
         *      A pair of values being pushed in from jspyder.form._fields
         *
         * @param {String} fieldSet.type
         *      The type of element being created.
         *
         * @param {Object} fieldSet.field
         *      A reference to the JS-DOM object containing the form fields.
         *
         * @param {String} name
         *      The name of the current field in the iterator.
         *
         * @param {Object} fields
         *      Reference to jspyder.form._fields
         *
         * @param {Object} context
         * @param {Object} context.values
         *      Reference to the field values which are being returned by
         *      jspyder.form.values
         *
         * @param {Object} context.self
         *      JS-Form
         */
        // _values: function (fieldSet, name, fields, context) {
        //     var self = context.self,
        //         values = context.values,
        //         $field = fieldSet.field,
        //         $type = fieldSet.type;

        //     values[name] = null;

        //     switch ($type) {
        //         case "checkbox":
        //             values[name] = self._checkboxValue($field);
        //             break;
        //         default:
        //             values[name] = self._genericValue($field);
        //             break;
        //     }

        //     return;
        // },

        /**
         * @method
         * @private
         *
         * Uses a generic value-retrieval method; this should be sufficient for
         * most single-value controls (e.g. not checkboxes)
         *
         * @param {Object} $input
         *      JS-DOM object to retrieve a value from.
         *
         * @return {String}
         *      The value of the element.
         */
        _genericValue: function ($input) {
            var value = "";

            if ($input) {
                $input.element(0, function () {
                    value = this.value;
                    if (typeof value === "undefined" || value === null) {
                        value = "";
                    }
                });
            }

            return value;
        },

        /**
         * @method
         * @private
         *
         * Specialized value retrieval for checkbox elements.
         */
        _checkboxValue: function ($checkboxes) {
            var value = [];

            if ($checkboxes) {
                $checkboxes.each(function (checkbox) {
                    if ((checkbox instanceof HTMLInputElement)
                        && (checkbox.getAttribute("type") === "checkbox")
                        && (checkbox.checked)) {
                        value.push(checkbox.value);
                    }
                });
            }

            return value;
        },

        fieldTemplate: {
            type: "input",
            values: [],
        },

        /**
         * @method
         *
         * Triggers a manual form submission.  If the form fails validation, or
         * any other errors occur, then the failed callback is executed.
         * Otherwise, the success function is executed.
         *
         * @param {Function} [onSuccess]
         *      Overrides the success function provided in the configuration on
         *      construction.  See jspyder.form constructor for expected
         *      parameters.
         *
         * @param {Function} [onFail]
         *      Overrides the failure function provided in the configuration on
         *      construction.  See jspyder.form constructor for expected
         *      parameters.
         */
        submit: function(onSuccess, onFail) {
            return this;
        },

        /**
         * @method
         *
         * Triggers a manual form reset.  This will turn all of the form fields
         * back to their initial values on creation.
         *
         * @param {Function} [fn]
         *      Optional callback to execute after the reset has been completed.
         *      See jspyder.form constructor for expected parameters.
         */
        reset: function(fn) {
            return this;
        },

        /**
         * @method
         *
         * Triggers a manual form reset.  This will turn all of the form fields
         * back to their initial values on creation.
         *
         * @param {Function} [fn]
         *      Optional callback to execute after the validation has been
         *      completed.  See jspyder.form constructor for expected
         *      parameters.
         */
        validate: function(fn) {
            return this;
        },

        /**
         * @method
         * Attaches the form to the specified dom node
         *
         * @param {Function} [fn]
         *      Optional callback function to execute, using the form js.dom
         *      element as the context and the js.form object as the first
         *      parameter.
         *
         * @param {Object} [fn.dom]
         *      DOM node created and attached to the document.
         *
         * @param {Mixed} [fn.data]
         *      Data parameter passed into the function.
         *
         * @param {Mixed} [data]
         *      Optional parameter to pass in as a second parameter for [fn].
         *
         * @return {Object} js.dom object.
         */
        attach: function (fn, data) {
            var dom = this._dom,
                fields = this._fields,
                name, group, section;

            for (name in fields) {
                group = fields[name];
                // group{ type, field, section }
            }

            // cycle through fields

            if(typeof fn === "function") {
                fn.apply(dom, [this, dom, data]);
            }

            return this;
        },
    };

    return js_form;
 });<|endoftext|>


<commit_before>var transpile = require('transpile');
var nodeDependencyMap = require("../node/dependency_map"),
	minify = require("../buildTypes/minifyJS"),
	transformActiveSource = require("../node/transform_active_source"),
	_ = require("lodash");

var transpileNode = function(node, outputFormat, options, graph){

	if( !node.load.metadata.buildType || node.load.metadata.buildType === "js"  ) {

		transformActiveSource(node,"format-"+outputFormat,function(node, source){
			var opts = _.clone(options);
			var depMap = nodeDependencyMap(node);

			if(opts.useNormalizedDependencies) {
				opts.normalizeMap = depMap;
			}
			// make sure load has activeSource
			var load = _.clone(node.load, true);
			load.source = source || load.source;
			// Minify globals prior to transpiling because they can't
			// be minified after they become a System.define.
			if(load.metadata.format === "global" && options.minify) {
				load.source = minify(load.source, options);
			}
			// I'm not sure how to handle defined.  "less" is an example of something we
			// define.  Presumably these should all be ignored.
			// also ignore any non js build type ... for now ...!
			var buildType = load.metadata.buildType || "js";
			if(load.metadata.format === "defined" || buildType !== "js") {
				return source;
			}
			if(opts.normalize) {

				var givenNormalize = opts.normalize;
				opts.normalize = function(name, curName){
					var normalizedName = options.useNormalizedDependencies ? name : depMap[name];
					var depLoad = graph[ normalizedName ].load;
					return givenNormalize.call(this, name, depLoad, curName, load);
				};
			}
			return transpile.to(load, outputFormat, opts);
		});
	}
};

// fullGraph - if graph is a bundle ... fullGraph is the actual graph
module.exports = function(graph, outputFormat, options, fullGraph){

	options = options || {};
	if(Array.isArray(graph)) {
		graph.forEach(function(node){
			transpileNode(node, outputFormat, options, fullGraph);
		});
	} else {
		for(var name in graph) {
			var node = graph[name];
			// If JavaScript
			transpileNode(node, outputFormat, options, graph);
		}
	}
};
<commit_msg>handles normalizing the current load better<commit_after>var transpile = require('transpile');
var nodeDependencyMap = require("../node/dependency_map"),
	minify = require("../buildTypes/minifyJS"),
	transformActiveSource = require("../node/transform_active_source"),
	_ = require("lodash");

var transpileNode = function(node, outputFormat, options, graph){

	if( !node.load.metadata.buildType || node.load.metadata.buildType === "js"  ) {

		transformActiveSource(node,"format-"+outputFormat,function(node, source){
			var opts = _.clone(options);
			var depMap = nodeDependencyMap(node);

			if(opts.useNormalizedDependencies) {
				opts.normalizeMap = depMap;
			}
			// make sure load has activeSource
			var load = _.clone(node.load, true);
			load.source = source || load.source;
			// Minify globals prior to transpiling because they can't
			// be minified after they become a System.define.
			if(load.metadata.format === "global" && options.minify) {
				load.source = minify(load.source, options);
			}
			// I'm not sure how to handle defined.  "less" is an example of something we
			// define.  Presumably these should all be ignored.
			// also ignore any non js build type ... for now ...!
			var buildType = load.metadata.buildType || "js";
			if(load.metadata.format === "defined" || buildType !== "js") {
				return source;
			}
			if(opts.normalize) {

				var givenNormalize = opts.normalize;
				opts.normalize = function(name, curName){
					// if name === curName ... it's asking to normalize the current module's name
					// for something like define('component/component',[...])
					// component/component won't be in depMap.
					var depLoad;
					if(name === curName) {
						depLoad = load;
					} else {
						var normalizedName = options.useNormalizedDependencies ? name : depMap[name];
						depLoad = graph[ normalizedName ].load;
					}
					return givenNormalize.call(this, name, depLoad, curName, load);
				};
			}
			return transpile.to(load, outputFormat, opts);
		});
	}
};

// fullGraph - if graph is a bundle ... fullGraph is the actual graph
module.exports = function(graph, outputFormat, options, fullGraph){

	options = options || {};
	if(Array.isArray(graph)) {
		graph.forEach(function(node){
			transpileNode(node, outputFormat, options, fullGraph);
		});
	} else {
		for(var name in graph) {
			var node = graph[name];
			// If JavaScript
			transpileNode(node, outputFormat, options, graph);
		}
	}
};
<|endoftext|>


<commit_before>'use strict';

var option = require('../../lib' + (process.env.MOVICO_COV || '') + '/Data/option.js').option;

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['options'] = {
  setUp: function(done) {
    done();
  },

  'option empty': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().isPresent(), false, 'should be empty option.');
    test.done();
  },

  'option not empty': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).isPresent(), true, 'should not be empty option.');
    test.done();
  },

  'option empty mapped': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().map(function(a){return a;}).isPresent(), false, 'should be empty option.');
    test.done();
  },

  'option not empty mapped': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).map(function(a){return a;}).get(), 12, 'should not be empty option.');
    test.done();
  },

  'option not empty flat mapped': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).flatMap(function(a){return option(a);}).get(), 12, 'should not be empty option.');
    test.done();
  },

  'option empty or else': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().orElse(12), 12, 'should be empty option.');
    test.done();
  },

  'option not empty or else': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).orElse(14), 12, 'should be empty option.');
    test.done();
  },
};
<commit_msg>Increase option tests<commit_after>'use strict';

var option = require('../../lib' + (process.env.MOVICO_COV || '') + '/Data/option.js').option;

/*
  ======== A Handy Little Nodeunit Reference ========
  https://github.com/caolan/nodeunit

  Test methods:
    test.expect(numAssertions)
    test.done()
  Test assertions:
    test.ok(value, [message])
    test.equal(actual, expected, [message])
    test.notEqual(actual, expected, [message])
    test.deepEqual(actual, expected, [message])
    test.notDeepEqual(actual, expected, [message])
    test.strictEqual(actual, expected, [message])
    test.notStrictEqual(actual, expected, [message])
    test.throws(block, [error], [message])
    test.doesNotThrow(block, [error], [message])
    test.ifError(value)
*/

exports['options'] = {
  setUp: function(done) {
    done();
  },

  'option empty': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().isPresent(), false, 'should be empty option.');
    test.done();
  },

  'option not empty': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).isPresent(), true, 'should not be empty option.');
    test.done();
  },

  'option empty mapped': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().map(function(a){return a;}).isPresent(), false, 'should be empty option.');
    test.done();
  },

  'option not empty mapped': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).map(function(a){return a;}).get(), 12, 'should not be empty option.');
    test.done();
  },

  'option not empty flat mapped to option': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).flatMap(function(a){return option(a);}).get(), 12, 'should not be empty option.');
    test.done();
  },

  'option not empty flat mapped to int': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).flatMap(function(a){return a;}).get(), 12, 'should not be empty option.');
    test.done();
  },

  'option empty flat mapped': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().flatMap(function(a){return a;}).isPresent(), false, 'should be empty option.');
    test.done();
  },

  'option empty or else': function(test) {
    test.expect(1);
    // tests here
    test.equal(option().orElse(12), 12, 'should be empty option.');
    test.done();
  },

  'option not empty or else': function(test) {
    test.expect(1);
    // tests here
    test.equal(option(12).orElse(14), 12, 'should be empty option.');
    test.done();
  },
};
<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var test = require('nodeunit');
var Spoiler = require('../../../app/models/spoiler');
var Media = require('../../../app/models/media');

var db;

db = mongoose.connect('mongodb://localhost/test');

module.exports = {

	"Should NOT create a spoiler without a media" : function(test){
		var spoiler = new Spoiler();

		test.throws(spoiler.save(function(error, spoiler) {
			test.done()
		}));
	},

	"Should NOT create a spoiler with a media but without a text": function(test) {
		var media = new Media({ title: 'The Sixth Sense' });

		var spoiler = new Spoiler({ media: media });

		test.throws(spoiler.save(function(error, spoiler) {
			test.done();
		}));
	},

	"Should insert a spoiler with media and text": function(test) {
		var media = new Media({ title: 'The Sixth Sense' });

		var spoiler = new Spoiler({
			media: media,
			text: 'Bruce Willis was dead since the beggining'
		});

		spoiler.save(function(error, spoiler) {
			if(error) console.log(error);

			test.equal(spoiler.media, media._id, "media id is wrong!");
			test.equal(spoiler.text, 'Bruce Willis was dead since the beggining');

			test.done();
		});
	},

	"Should insert multiple spoilers in a single media": function(test) {
		var media = new Media({ title: 'Game of Thrones' });

		var spoiler1 = {
			media: media,
			text: 'Ned Stark dies'
		};

		var spoiler2 = {
			media: media,
			text: 'Everybody else dies'
		};

		Spoiler.create(spoiler1, spoiler2, function(error, spoiler1, spoiler2) {
			if(error) console.log(error);

			test.equals(spoiler1.media, media._id);
			test.equals(spoiler2.media, media._id);

			test.done()
		}).then(media.save());
	},

	"Should query multipĺe spoilers media": function(test) {
		Media.findOne({ title: 'Game of Thrones' }, function(error, media) {
			if(error) console.log(error);
		}).exec(function(error, media){

			Spoiler.find({ media: media._id }, function(error, spoilers) {
				if(error) console.log(error);

				test.equals(spoilers[0].text, 'Ned Stark dies');
				test.equals(spoilers[1].text, 'Everybody else dies');

				test.done();
			});
		});

	},

	"Should delete a spoiler given it's id": function(test) {
		Spoiler.findOne({ text: 'Ned Stark dies' }, function(error, spoiler) {
			if(error) console.log(error);
		}).exec(function(error, spoiler){

			Spoiler.remove({ _id: spoiler._id }, function(error) {
				if(error) console.log(error);

				test.done();
			});

		});
	},

	"Cleaning up database...": function(test) {
		Spoiler.remove({}, function(){})
			.exec(Media.remove({}, function(){}))
			.then(db.disconnect());
		test.done();
	}
};<commit_msg>Fixing tests for spoiler<commit_after>var mongoose = require('mongoose');
var test = require('nodeunit');
var Spoiler = require('../../../app/models/spoiler');
var Media = require('../../../app/models/media');

var db;

db = mongoose.connect('mongodb://localhost/test');

module.exports = {

	"Should NOT create a spoiler without a media" : function(test){
		var spoiler = new Spoiler();

		test.throws(spoiler.save(function(error, spoiler) {
			test.done()
		}));
	},

	"Should NOT create a spoiler with a media but without a text": function(test) {
		var media = new Media({ title: 'The Sixth Sense' });

		var spoiler = new Spoiler({ media: media });

		test.throws(spoiler.save(function(error, spoiler) {
			test.done();
		}));
	},

	"Should insert a spoiler with media and text": function(test) {
		var media = new Media({ title: 'The Sixth Sense' });

		var spoiler = new Spoiler({
			media: media,
			text: 'Bruce Willis was dead since the beggining'
		});

		spoiler.save(function(error, spoiler) {
			if(error) console.log(error);

			test.equal(spoiler.media, media._id, "media id is wrong!");
			test.equal(spoiler.text, 'Bruce Willis was dead since the beggining');

			test.done();
		});
	},

	"Should insert multiple spoilers in a single media": function(test) {
		var media = new Media({ title: 'Game of Thrones' });

		var spoiler1 = {
			media: media,
			text: 'Ned Stark dies'
		};

		var spoiler2 = {
			media: media,
			text: 'Everybody else dies'
		};

		Spoiler.create(spoiler1, spoiler2, function(error, spoiler1, spoiler2) {
			if(error) console.log(error);

			test.equals(spoiler1.media, media._id);
			test.equals(spoiler2.media, media._id);

			test.done()
		}).then(media.save());
	},

	"Should query multipĺe spoilers media": function(test) {
		Media.findOne({ title: 'Game of Thrones' }, function(error, media) {
			if(error) console.log(error);
		}).exec(function(error, media){

			Spoiler.find({ media: media._id }, function(error, spoilers) {
				if(error) console.log(error);

				test.equals(spoilers[0].text, 'Ned Stark dies');
				test.equals(spoilers[1].text, 'Everybody else dies');

				test.done();
			});
		});

	},

	"Should delete a spoiler given it's id": function(test) {
		Spoiler.findOne({ text: 'Ned Stark dies' }, function(error, spoiler) {
			if(error) console.log(error);
		}).exec(function(error, spoiler){
			var media = spoiler.media;

			Spoiler.remove({ _id: spoiler._id }, function(error) {
				if(error) console.log(error);

			}).exec(function() {
				Spoiler.find({ media: media }, function(error, spoilers) {
					if(error) console.log(error);

					test.equals(spoilers.length, 1);

					test.done();
				});
			});

		});
	},

	"Cleaning up database...": function(test) {
		Spoiler.remove({}, function(){})
			.exec(Media.remove({}, function(){}))
			.then(db.disconnect());
		test.done();
	}
};<|endoftext|>