<commit_before>'use strict';

var assert = require('assert');

var Node = require('../../lib/node/node');

describe('node-creation', function() {

    var owner = 'localhost';

    describe('reserved keywords', function() {
        it('should fail for reserved param names', function() {
            var ReservedKeywordNode;
            assert.throws(
                function() {
                    ReservedKeywordNode = Node.create('test-reserved-keyword', { type: Node.PARAM.STRING() });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid param name "type". It is a reserved keyword.'
                    );
                    return true;
                }
            );
        });

    });

    var TestSource = Node.create('test-source', {query: Node.PARAM.STRING()});

    it('should validate params', function() {
        var QUERY = 'select * from table';
        var source = new TestSource(owner, { query: QUERY });
        assert.equal(source.query, QUERY);
    });

    it('should fail for missing params', function() {
        var source;
        assert.throws(
            function() {
                 source = new TestSource(owner, {});
            },
            function(err) {
                assert.equal(err.message, 'Missing required param "query"');
                return true;
            }
        );
    });

    it('should fail for invalid param type', function() {
        var source;
        assert.throws(
            function() {
                source = new TestSource(owner, { query: 2 });
            },
            function(err) {
                assert.equal(err.message, 'Invalid type for param "query", expects "string" type, got `2`');
                return true;
            }
        );
    });

    describe('Node.PARAM.ENUM', function() {
        var EnumSource = Node.create('test-source', { classification: Node.PARAM.ENUM('knn', 'queen') });

        it('should check ENUM uses one of the values', function() {
            var CLASSIFICATIONS = ['knn', 'queen'];
            CLASSIFICATIONS.forEach(function(classification) {
                var enumSource = new EnumSource(owner, { classification: classification });
                assert.equal(enumSource.classification, classification);
            });
        });

        it('should fail for invalid ENUM values', function() {
            var enumSource;
            assert.throws(
                function() {
                    enumSource = new EnumSource(owner, { classification: 'wadus' });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid type for param "classification", expects "enum("knn","queen")" type, got `"wadus"`'
                    );
                    return true;
                }
            );
        });

    });

    describe('Node.PARAM.NULLABLE', function() {
        var NullableNode = Node.create('test-nullable', {
            mandatory: Node.PARAM.STRING(),
            optional: Node.PARAM.NULLABLE(Node.PARAM.STRING())
        });

        it('should work for valid params', function() {
            var nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: 'wadus_optional' });
            assert.equal(nullableNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableNode.optional, 'wadus_optional');
        });

        it('should fail for invalid PARAM type', function() {
            var nullableNode;
            assert.throws(
                function() {
                    nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: 1 });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid type for param "optional", expects "string" type, got `1`'
                    );
                    return true;
                }
            );
        });

        it('should fail for invalid PARAM type with falsy values', function() {
            var nullableNode;
            assert.throws(
                function() {
                    nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: 0 });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid type for param "optional", expects "string" type, got `0`'
                    );
                    return true;
                }
            );
        });

        it('should allow to use null values for NULLABLE params', function() {
            var nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: null });
            assert.equal(nullableNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableNode.optional, null);
        });

        it('should allow to use undefined values for NULLABLE params', function() {
            var nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory' });
            assert.equal(nullableNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableNode.optional, null);
        });

    });

    describe('Node.PARAM.ARRAY', function() {
        var ListNode = Node.create('test-array', {
            list: Node.PARAM.ARRAY()
        });

        it('should work for mixed arrays', function() {
            var listNode = new ListNode(owner, { list: [ 1, 'wadus' ] });
            assert.deepEqual(listNode.list, [ 1, 'wadus' ]);
        });

        it('should work for empty arrays', function() {
            var listNode = new ListNode(owner, { list: [] });
            assert.deepEqual(listNode.list, []);
        });

        describe('typed array', function() {
            var StringTypedListNode = Node.create('test-array-string', {
                list: Node.PARAM.ARRAY(Node.PARAM.STRING())
            });

            var NumberTypedListNode = Node.create('test-array-string', {
                list: Node.PARAM.ARRAY(Node.PARAM.NUMBER())
            });

            it('should work for string arrays', function() {
                var listNode = new StringTypedListNode(owner, { list: [ 'wadus', 'wadus' ] });
                assert.deepEqual(listNode.list, [ 'wadus', 'wadus' ]);
            });

            it('should work for number arrays', function() {
                var listNode = new NumberTypedListNode(owner, { list: [ 1, 2, 3, 4 ] });
                assert.deepEqual(listNode.list, [ 1, 2, 3, 4 ]);
            });

            it('should fail for mixed arrays', function() {
                var listNode;

                assert.throws(
                    function() {
                        listNode = new StringTypedListNode(owner, { list: [ 1, 'wadus' ] });
                    },
                    function(err) {
                        assert.equal(
                            err.message,
                            'Invalid type for param "list", expects "array<string>" type, got `[1,"wadus"]`'
                        );
                        return true;
                    }
                );
            });

            it('should fail for mixed arrays', function() {
                var listNode;

                assert.throws(
                    function() {
                        listNode = new NumberTypedListNode(owner, { list: [ 1, 'wadus' ] });
                    },
                    function(err) {
                        assert.equal(
                            err.message,
                            'Invalid type for param "list", expects "array<number>" type, got `[1,"wadus"]`'
                        );
                        return true;
                    }
                );
            });

            describe('nullable', function() {
                var NullableStringTypedListNode = Node.create('test-array-string', {
                    list: Node.PARAM.NULLABLE(Node.PARAM.ARRAY(Node.PARAM.STRING()))
                });

                it('should work for null param', function() {
                    var listNode = new NullableStringTypedListNode(owner, {});
                    assert.equal(listNode.list, null);
                });

                it('still should fail for mixed arrays', function() {
                    var listNode;

                    assert.throws(
                        function() {
                            listNode = new NullableStringTypedListNode(owner, { list: [ 1, 'wadus' ] });
                        },
                        function(err) {
                            assert.equal(
                                err.message,
                                'Invalid type for param "list", expects "array<string>" type, got `[1,"wadus"]`'
                            );
                            return true;
                        }
                    );
                });

            });
        });
    });

    describe('Node custom validate', function() {
        var validList = [1, 2, 3, 4];
        var CustomValidationNode = Node.create('test-custom-validation', { list: Node.PARAM.ARRAY() }, {
            beforeCreate: function(node) {
                assert.deepEqual(node.list, validList, 'Custom validation throws this');
            }
        });

        it('should work for expected array list', function () {
            var customValidationNode = new CustomValidationNode(owner, { list: validList });
            assert.deepEqual(customValidationNode.list, validList);
        });

        it('should fail for unexpected array list', function() {
            var customValidationNode;

            assert.throws(
                function() {
                    customValidationNode = new CustomValidationNode(owner, { list: [1] });
                },
                function(err) {
                    assert.equal(err.message, 'Custom validation throws this');
                    return true;
                }
            );
        });
    });

    describe('Node ignoreParamForId', function() {
        var ANode = Node.create('test-a-with-ignored-b', { a: Node.PARAM.STRING() });
        var ABNode = Node.create('test-a-with-ignored-b', { a: Node.PARAM.STRING(), b: Node.PARAM.STRING() });
        var AIgnoredBNode = Node.create('test-a-with-ignored-b', { a: Node.PARAM.STRING(), b: Node.PARAM.STRING() }, {
            beforeCreate: function(node) {
                node.ignoreParamForId('b');
            }
        });

        it('should have different id for A and AB nodes', function () {
            var aNode = new ANode(owner, {a: 'a'});
            var abNode = new ABNode(owner, {a: 'a', b: 'b'});
            assert.notEqual(aNode.id(), abNode.id());
        });

        it('should have same id for A and AIgnoredB nodes', function () {
            var aNode = new ANode(owner, {a: 'a'});
            var abNode = new AIgnoredBNode(owner, {a: 'a', b: 'b'});
            assert.equal(aNode.id(), abNode.id());
        });
    });

    describe('Node validator defaultValue', function() {
        var nullableParamTypes = Object.keys(Node.PARAM)
            .filter(function(paramType) { return paramType !== 'NULLABLE' && paramType !== 'NODE'; });

        nullableParamTypes.forEach(function(paramType) {
            it('should default to null for non provided "' + paramType + '" param', function () {
                var ANode = Node.create('test-default-value-' + paramType, {
                    a: Node.PARAM.NULLABLE(Node.PARAM[paramType]())
                });
                var aNode = new ANode(owner, {});
                assert.equal(aNode.a, null);
            });
        });

        it('should default to first value for non provided ENUM value', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM('a', 'b', 'c'))
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, 'a');
        });

        it('can override default value with nullable param', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM('a', 'b', 'c'), 'b')
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, 'b');
        });

        it('can use boolean false values', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM(false, true))
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, false);
        });

        it('can override with false false value', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM(true, false), false)
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, false);
        });
    });

    describe('Cached table names', function() {

        it('should be 60 chars at max for long type names', function() {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.STRING())
            });

            var aNode = new ANode(owner, {});
            assert.equal(aNode.getTargetTable().length, 60);
        });

        it('should be 60 chars also for short type names', function() {
            var ANode = Node.create('t', {
                a: Node.PARAM.NULLABLE(Node.PARAM.STRING())
            });

            var aNode = new ANode(owner, {});
            assert.equal(aNode.getTargetTable().length, 60);
        });

    });

});
<commit_msg>Going red: add test to fail on optional Node param<commit_after>'use strict';

var assert = require('assert');

var Node = require('../../lib/node/node');

describe('node-creation', function() {

    var owner = 'localhost';

    describe('reserved keywords', function() {
        it('should fail for reserved param names', function() {
            var ReservedKeywordNode;
            assert.throws(
                function() {
                    ReservedKeywordNode = Node.create('test-reserved-keyword', { type: Node.PARAM.STRING() });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid param name "type". It is a reserved keyword.'
                    );
                    return true;
                }
            );
        });

    });

    var TestSource = Node.create('test-source', {query: Node.PARAM.STRING()});

    it('should validate params', function() {
        var QUERY = 'select * from table';
        var source = new TestSource(owner, { query: QUERY });
        assert.equal(source.query, QUERY);
    });

    it('should fail for missing params', function() {
        var source;
        assert.throws(
            function() {
                 source = new TestSource(owner, {});
            },
            function(err) {
                assert.equal(err.message, 'Missing required param "query"');
                return true;
            }
        );
    });

    it('should fail for invalid param type', function() {
        var source;
        assert.throws(
            function() {
                source = new TestSource(owner, { query: 2 });
            },
            function(err) {
                assert.equal(err.message, 'Invalid type for param "query", expects "string" type, got `2`');
                return true;
            }
        );
    });

    describe('Node.PARAM.ENUM', function() {
        var EnumSource = Node.create('test-source', { classification: Node.PARAM.ENUM('knn', 'queen') });

        it('should check ENUM uses one of the values', function() {
            var CLASSIFICATIONS = ['knn', 'queen'];
            CLASSIFICATIONS.forEach(function(classification) {
                var enumSource = new EnumSource(owner, { classification: classification });
                assert.equal(enumSource.classification, classification);
            });
        });

        it('should fail for invalid ENUM values', function() {
            var enumSource;
            assert.throws(
                function() {
                    enumSource = new EnumSource(owner, { classification: 'wadus' });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid type for param "classification", expects "enum("knn","queen")" type, got `"wadus"`'
                    );
                    return true;
                }
            );
        });

    });

    describe('Node.PARAM.NULLABLE', function() {
        var NullableNode = Node.create('test-nullable', {
            mandatory: Node.PARAM.STRING(),
            optional: Node.PARAM.NULLABLE(Node.PARAM.STRING())
        });

        it('should work for valid params', function() {
            var nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: 'wadus_optional' });
            assert.equal(nullableNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableNode.optional, 'wadus_optional');
        });

        it('should fail for invalid PARAM type', function() {
            var nullableNode;
            assert.throws(
                function() {
                    nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: 1 });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid type for param "optional", expects "string" type, got `1`'
                    );
                    return true;
                }
            );
        });

        it('should fail for invalid PARAM type with falsy values', function() {
            var nullableNode;
            assert.throws(
                function() {
                    nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: 0 });
                },
                function(err) {
                    assert.equal(
                        err.message,
                        'Invalid type for param "optional", expects "string" type, got `0`'
                    );
                    return true;
                }
            );
        });

        it('should allow to use null values for NULLABLE params', function() {
            var nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory', optional: null });
            assert.equal(nullableNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableNode.optional, null);
        });

        it('should allow to use undefined values for NULLABLE params', function() {
            var nullableNode = new NullableNode(owner, { mandatory: 'wadus_mandatory' });
            assert.equal(nullableNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableNode.optional, null);
        });

        it('should accept accept nullable geometry params', function() {
            var NullableGeometryNode = Node.create('test-geometry-nullable', {
                mandatory: Node.PARAM.STRING(),
                optional_node: Node.PARAM.NULLABLE(Node.PARAM.NODE())
            });
            var nullableGeometryNode = new NullableGeometryNode(owner, {
                mandatory: 'wadus_mandatory'
            });

            assert.equal(nullableGeometryNode.mandatory, 'wadus_mandatory');
            assert.equal(nullableGeometryNode.optional_node, null);
        });

    });

    describe('Node.PARAM.ARRAY', function() {
        var ListNode = Node.create('test-array', {
            list: Node.PARAM.ARRAY()
        });

        it('should work for mixed arrays', function() {
            var listNode = new ListNode(owner, { list: [ 1, 'wadus' ] });
            assert.deepEqual(listNode.list, [ 1, 'wadus' ]);
        });

        it('should work for empty arrays', function() {
            var listNode = new ListNode(owner, { list: [] });
            assert.deepEqual(listNode.list, []);
        });

        describe('typed array', function() {
            var StringTypedListNode = Node.create('test-array-string', {
                list: Node.PARAM.ARRAY(Node.PARAM.STRING())
            });

            var NumberTypedListNode = Node.create('test-array-string', {
                list: Node.PARAM.ARRAY(Node.PARAM.NUMBER())
            });

            it('should work for string arrays', function() {
                var listNode = new StringTypedListNode(owner, { list: [ 'wadus', 'wadus' ] });
                assert.deepEqual(listNode.list, [ 'wadus', 'wadus' ]);
            });

            it('should work for number arrays', function() {
                var listNode = new NumberTypedListNode(owner, { list: [ 1, 2, 3, 4 ] });
                assert.deepEqual(listNode.list, [ 1, 2, 3, 4 ]);
            });

            it('should fail for mixed arrays', function() {
                var listNode;

                assert.throws(
                    function() {
                        listNode = new StringTypedListNode(owner, { list: [ 1, 'wadus' ] });
                    },
                    function(err) {
                        assert.equal(
                            err.message,
                            'Invalid type for param "list", expects "array<string>" type, got `[1,"wadus"]`'
                        );
                        return true;
                    }
                );
            });

            it('should fail for mixed arrays', function() {
                var listNode;

                assert.throws(
                    function() {
                        listNode = new NumberTypedListNode(owner, { list: [ 1, 'wadus' ] });
                    },
                    function(err) {
                        assert.equal(
                            err.message,
                            'Invalid type for param "list", expects "array<number>" type, got `[1,"wadus"]`'
                        );
                        return true;
                    }
                );
            });

            describe('nullable', function() {
                var NullableStringTypedListNode = Node.create('test-array-string', {
                    list: Node.PARAM.NULLABLE(Node.PARAM.ARRAY(Node.PARAM.STRING()))
                });

                it('should work for null param', function() {
                    var listNode = new NullableStringTypedListNode(owner, {});
                    assert.equal(listNode.list, null);
                });

                it('still should fail for mixed arrays', function() {
                    var listNode;

                    assert.throws(
                        function() {
                            listNode = new NullableStringTypedListNode(owner, { list: [ 1, 'wadus' ] });
                        },
                        function(err) {
                            assert.equal(
                                err.message,
                                'Invalid type for param "list", expects "array<string>" type, got `[1,"wadus"]`'
                            );
                            return true;
                        }
                    );
                });

            });
        });
    });

    describe('Node custom validate', function() {
        var validList = [1, 2, 3, 4];
        var CustomValidationNode = Node.create('test-custom-validation', { list: Node.PARAM.ARRAY() }, {
            beforeCreate: function(node) {
                assert.deepEqual(node.list, validList, 'Custom validation throws this');
            }
        });

        it('should work for expected array list', function () {
            var customValidationNode = new CustomValidationNode(owner, { list: validList });
            assert.deepEqual(customValidationNode.list, validList);
        });

        it('should fail for unexpected array list', function() {
            var customValidationNode;

            assert.throws(
                function() {
                    customValidationNode = new CustomValidationNode(owner, { list: [1] });
                },
                function(err) {
                    assert.equal(err.message, 'Custom validation throws this');
                    return true;
                }
            );
        });
    });

    describe('Node ignoreParamForId', function() {
        var ANode = Node.create('test-a-with-ignored-b', { a: Node.PARAM.STRING() });
        var ABNode = Node.create('test-a-with-ignored-b', { a: Node.PARAM.STRING(), b: Node.PARAM.STRING() });
        var AIgnoredBNode = Node.create('test-a-with-ignored-b', { a: Node.PARAM.STRING(), b: Node.PARAM.STRING() }, {
            beforeCreate: function(node) {
                node.ignoreParamForId('b');
            }
        });

        it('should have different id for A and AB nodes', function () {
            var aNode = new ANode(owner, {a: 'a'});
            var abNode = new ABNode(owner, {a: 'a', b: 'b'});
            assert.notEqual(aNode.id(), abNode.id());
        });

        it('should have same id for A and AIgnoredB nodes', function () {
            var aNode = new ANode(owner, {a: 'a'});
            var abNode = new AIgnoredBNode(owner, {a: 'a', b: 'b'});
            assert.equal(aNode.id(), abNode.id());
        });
    });

    describe('Node validator defaultValue', function() {
        var nullableParamTypes = Object.keys(Node.PARAM)
            .filter(function(paramType) { return paramType !== 'NULLABLE' && paramType !== 'NODE'; });

        nullableParamTypes.forEach(function(paramType) {
            it('should default to null for non provided "' + paramType + '" param', function () {
                var ANode = Node.create('test-default-value-' + paramType, {
                    a: Node.PARAM.NULLABLE(Node.PARAM[paramType]())
                });
                var aNode = new ANode(owner, {});
                assert.equal(aNode.a, null);
            });
        });

        it('should default to first value for non provided ENUM value', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM('a', 'b', 'c'))
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, 'a');
        });

        it('can override default value with nullable param', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM('a', 'b', 'c'), 'b')
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, 'b');
        });

        it('can use boolean false values', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM(false, true))
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, false);
        });

        it('can override with false false value', function () {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.ENUM(true, false), false)
            });
            var aNode = new ANode(owner, {});
            assert.equal(aNode.a, false);
        });
    });

    describe('Cached table names', function() {

        it('should be 60 chars at max for long type names', function() {
            var ANode = Node.create('test-default-value', {
                a: Node.PARAM.NULLABLE(Node.PARAM.STRING())
            });

            var aNode = new ANode(owner, {});
            assert.equal(aNode.getTargetTable().length, 60);
        });

        it('should be 60 chars also for short type names', function() {
            var ANode = Node.create('t', {
                a: Node.PARAM.NULLABLE(Node.PARAM.STRING())
            });

            var aNode = new ANode(owner, {});
            assert.equal(aNode.getTargetTable().length, 60);
        });

    });

});
<|endoftext|>


<commit_before>var Response = require("ringo/webapp/response").Response;
var Request = require("ringo/webapp/request").Request;

var urls = [
    [(/^\/(index(.html)?)?/), require("./root/index").app],
    [(/^\/(login)/), require("./root/login").app],
    [(/^\/(proxy)/), require("./root/proxy").app],
    [(/^\/(maps(\/\d+)?)/), require("./root/maps").app],
    [(/^\/(composer)/), require("./root/composer").app],
    [(/^\/(viewer(.html)?)/), require("./root/viewer").app]
];

// debug mode loads unminified scripts
if (java.lang.System.getProperty("app.debug")) {
    var FS = require("fs");
    var config = FS.normal(FS.join(module.directory, "..", "buildjs.cfg"));
    urls.push(
        [(/^\/script(\/.*)/), require("./autoloader").App(config)]
    );

    // proxy a remote geoserver on /geoserver by setting proxy.geoserver to remote URL
    // only recommended for debug mode
    var geoserver = java.lang.System.getProperty("app.proxy.geoserver");
    if (geoserver) {
        if (geoserver.charAt(geoserver.length-1) !== "/") {
            geoserver = geoserver + "/";
        }
        // debug specific proxy
        urls.push(
            [(/^\/geoserver\/(.*)/), require("./root/proxy").pass({url: geoserver, allowAuth: true})]
        );
    }
}

exports.urls = urls;

// TODO: remove if http://github.com/ringo/ringojs/issues/issue/98 is addressed
function slash(config) {
    return function(app) {
        return function(request) {
            var response;
            var servletRequest = request.env.servletRequest;
            var pathInfo = servletRequest.getPathInfo();
            if (pathInfo === "/") {
                var uri = servletRequest.getRequestURI();
                if (uri.charAt(uri.length-1) !== "/") {
                    var location = servletRequest.getScheme() + "://" +
                        servletRequest.getServerName() + ":" + servletRequest.getServerPort() +
                        uri + "/";
                    return {
                        status: 301,
                        headers: {"Location": location},
                        body: []
                    };
                }
            }
            return app(request);
        };
    };
}

exports.middleware = [
    slash(),
    require("ringo/middleware/gzip").middleware,
    require("ringo/middleware/static").middleware({base: module.resolve("static")}),
    require("ringo/middleware/error").middleware,
    require("ringo/middleware/notfound").middleware
];

exports.app = require("ringo/webapp").handleRequest;

exports.charset = "UTF-8";
exports.contentType = "text/html";
<commit_msg>Setting preserveHost to true and documenting the implications.<commit_after>var Response = require("ringo/webapp/response").Response;
var Request = require("ringo/webapp/request").Request;

var urls = [
    [(/^\/(index(.html)?)?/), require("./root/index").app],
    [(/^\/(login)/), require("./root/login").app],
    [(/^\/(proxy)/), require("./root/proxy").app],
    [(/^\/(maps(\/\d+)?)/), require("./root/maps").app],
    [(/^\/(composer)/), require("./root/composer").app],
    [(/^\/(viewer(.html)?)/), require("./root/viewer").app]
];

// debug mode loads unminified scripts
if (java.lang.System.getProperty("app.debug")) {
    var FS = require("fs");
    var config = FS.normal(FS.join(module.directory, "..", "buildjs.cfg"));
    urls.push(
        [(/^\/script(\/.*)/), require("./autoloader").App(config)]
    );

    // proxy a remote geoserver on /geoserver by setting proxy.geoserver to remote URL
    // only recommended for debug mode
    var geoserver = java.lang.System.getProperty("app.proxy.geoserver");
    if (geoserver) {
        if (geoserver.charAt(geoserver.length-1) !== "/") {
            geoserver = geoserver + "/";
        }
        // debug specific proxy
        urls.push(
            [(/^\/geoserver\/(.*)/), require("./root/proxy").pass({
                url: geoserver,
                allowAuth: true,
                /**
                 * Setting preserveHost to true makes it so GeoServer advertises
                 * URLs on the same origin as this app.  That makes it so the
                 * proxy is not involved in any requests issued to this same
                 * GeoServer.  The reason this is required is because we want
                 * to preserve auth related headers in requests to GeoServer and
                 * we don't want to send those same auth related headers to
                 * every service that is proxied.  The negative side effect is
                 * that the proxy will occasionally fail due to
                 * java.lang.OutOfMemoryError issues.
                 * TODO: figure out why so much memory is being consumed in proxy
                 */
                preserveHost: true
            })]
        );
    }
}

exports.urls = urls;

// TODO: remove if http://github.com/ringo/ringojs/issues/issue/98 is addressed
function slash(config) {
    return function(app) {
        return function(request) {
            var response;
            var servletRequest = request.env.servletRequest;
            var pathInfo = servletRequest.getPathInfo();
            if (pathInfo === "/") {
                var uri = servletRequest.getRequestURI();
                if (uri.charAt(uri.length-1) !== "/") {
                    var location = servletRequest.getScheme() + "://" +
                        servletRequest.getServerName() + ":" + servletRequest.getServerPort() +
                        uri + "/";
                    return {
                        status: 301,
                        headers: {"Location": location},
                        body: []
                    };
                }
            }
            return app(request);
        };
    };
}

exports.middleware = [
    slash(),
    require("ringo/middleware/gzip").middleware,
    require("ringo/middleware/static").middleware({base: module.resolve("static")}),
    require("ringo/middleware/error").middleware,
    require("ringo/middleware/notfound").middleware
];

exports.app = require("ringo/webapp").handleRequest;

exports.charset = "UTF-8";
exports.contentType = "text/html";
<|endoftext|>


<commit_before>
    function validateRequired(form) {
        var isValid = true;
        var focusField = null;
        var i = 0;
        var fields = new Array();
        oRequired = new required();
        for (x in oRequired) {
            var field = form[oRequired[x][0]];

            if (field.type == 'text' ||
                field.type == 'textarea' ||
                field.type == 'file' ||
                field.type == 'select-one' ||
                field.type == 'radio' ||
                field.type == 'password') {

                var value = '';
                // get field's value
                if (field.type == "select-one") {
                    var si = field.selectedIndex;
                    if (si >= 0) {
                        value = field.options[si].value;
                    }
                } else {
                    value = field.value;
                }

                if (value == '') {

                    if (i == 0) {
                        focusField = field;
                    }
                    fields[i++] = oRequired[x][1];
                    isValid = false;
                }
            }
        }
        if (fields.length > 0) {
           focusField.focus();
           alert(fields.join('\n'));
        }
        return isValid;
    }<commit_msg>Copy changes from Struts for PR# 21051.<commit_after>
    function validateRequired(form) {
        var isValid = true;
        var focusField = null;
        var i = 0;
        var fields = new Array();
        oRequired = new required();
        for (x in oRequired) {
            var field = form[oRequired[x][0]];

            if (field.type == 'text' ||
                field.type == 'textarea' ||
                field.type == 'file' ||
                field.type == 'select-one' ||
                field.type == 'radio' ||
                field.type == 'password') {

                var value = '';
                // get field's value
                if (field.type == "select-one") {
                    var si = field.selectedIndex;
                    if (si >= 0) {
                        value = field.options[si].value;
                    }
                } else {
                    value = field.value;
                }

                if (trim(value).length == 0) {

                    if (i == 0) {
                        focusField = field;
                    }
                    fields[i++] = oRequired[x][1];
                    isValid = false;
                }
            }
        }
        if (fields.length > 0) {
           focusField.focus();
           alert(fields.join('\n'));
        }
        return isValid;
    }

    // Trim whitespace from left and right sides of s.
    function trim(s) {
        return s.replace( /^\s*/, "" ).replace( /\s*$/, "" );
    }<|endoftext|>


<commit_before>exports = module.exports = new Build();

var path = require('path');
var fs = require('fs');
var Q = require('q');

function mkdir(dirPath) {
	var defer = Q.defer();
	fs.mkdir(dirPath, function() {
		defer.resolve(true);
	});
	return defer.promise;
}

function unloadModules(basePath) {
	var name = require.resolve('fire');
	if(typeof require.cache[name] != 'undefined') {
		delete require.cache[name];
	}

	var moduleName = require.resolve(path.join(basePath, 'index.js'));
	if(typeof require.cache[moduleName] != 'undefined') {
		delete require.cache[moduleName];
	}

	Object.keys(require.cache).forEach(function(requireName) {
		if(requireName.indexOf(basePath) === 0) {
			delete require.cache[requireName];
		}
	});
}

function loadApp(basePath) {
	unloadModules(basePath);

	var fire = require('../../../');
	fire.disabled = true;
	fire.appsMap = {};

	require(path.join(basePath, 'index.js'));

	return fire.app(Object.keys(fire.appsMap)[0]);
}

function Build() {

}

Build.prototype.extendConfig = function(gruntConfig, grunt) {
	if(!gruntConfig.firebuild) {
		gruntConfig.firebuild = {};
	}

	gruntConfig.firebuild.migrations = {};
	gruntConfig.firebuild.api = {};
	gruntConfig.firebuild.scripts = {};

	var optionsApp = loadApp(process.cwd());

	gruntConfig.less = {
		src: {
			expand: true,
			src: ['./styles/*.less'],
			dest: 'public/',
			ext: '.css'
		}
	};

	gruntConfig.jade = {
		compile: {
			options: {
				data: optionsApp._options
			},
			files: [{
				expand: true,
				src: 'templates/**/*.jade',
				dest: 'public/',
				ext: '.html'
			}]
		}
	};

	gruntConfig.uglify = {
		/*
		options: {
			banner: ''
		},
		 */
		build: {
			src: 'public/scripts/fire.js',
			dest: 'public/scripts/fire.min.js'
		}
	};

	if(!gruntConfig.release) {
		gruntConfig.release = {};
	}

	gruntConfig.release.migrate = {};

	if(!gruntConfig.run) {
		gruntConfig.run = {};
	}

	grunt.registerMultiTask('release', function(version) {
		var dotenv = require('dotenv');
		dotenv.load();

		var Migrations = require('../migrations');

		var basePath = process.cwd();
		var app = loadApp(basePath);

		app.models.forEach(function(model, modelName) {
			delete app.models.internals[modelName];
			delete app.models[modelName];
		});

		var models = app.models; //new Models(app);
		var migrations = new Migrations();

		var targetVersion = version;

		var done = this.async();

		// Set-up without reading any of the models
		// We will create the models based on all migrations

		models.setup(null)
			.then(function() {
				return migrations.setup(path.join(basePath, '_migrations'), models);
			})
			.then(function() {
				if(migrations._.length === 0) {
					throw new Error('There are 0 migration files. Did you run `fire generate migrations`?');
				}
			})
			.then(function() {
				// Let's find which database version we're at
				return migrations.currentVersion();
			})
			.then(function(currentVersion) {
				if(!targetVersion) {
					targetVersion = migrations._[migrations._.length - 1].version;
				}

				if(targetVersion == currentVersion) {
					console.log('*** Database is up-to-date.');
				}
				else {
					console.log('*** Migrating from `' + currentVersion + '` to `' + targetVersion + '`.');

					return migrations.migrate(currentVersion, targetVersion)
						.then(function() {
							return migrations.currentVersion();
						})
						.then(function(newVersion) {
							if(newVersion == targetVersion) {
								//everything went alright
								console.log('*** Migration successful to `' + targetVersion + '`.');
							}
							else {
								throw new Error('Database version after migration `' + newVersion + '` does not match target version `' + targetVersion + '`.');
							}
						});
				}
			})
			.then(function() {
				done();
			})
			.catch(function(error) {
				console.log(error.message);
				console.log(error.stack);

				throw error;
			})
			.done();
	});

	grunt.registerMultiTask('firebuild', function() {
		var done = this.async();
		var basePath = process.cwd();

		var app = loadApp(basePath);

		if(this.target == 'migrations') {
			mkdir(path.join(basePath, '_migrations'))
				.then(function() {
					var Generate = require('../migrations/generate');
					var generate = new Generate(app, basePath);
					generate.delegate = {
						addMigration: function(fileName, stream) {
							var writeStream = fs.createWriteStream(path.join(basePath, '_migrations', fileName));
							stream.pipe(writeStream);

							writeStream.once('finish', function() {
								done();
							});
						}
					};

					return generate.createMigrations(true);
				})
				.then(function(result) {
					if(!result) {
						// If the result is false, there are no migrations so we'll call done.
						done();
					}
				})
				.done();
		}
		else if(this.target == 'api') {
			app.controllers.setup(basePath)
				.then(function() {
					return app.models.setup(basePath);
				})
				.then(function() {
					var defer = Q.defer();

					setImmediate(function() {
						fs.mkdir(path.join(basePath, '_api'), function() {
							defer.resolve();
						});
					});

					return defer.promise;
				})
				.then(function() {
					var result = Q.when(true);

					app.models.forEach(function(model) {
						result = result.then(function() {
							var writeStream = fs.createWriteStream(path.join(basePath, '_api', model.getFileName() + '.js'));
							return app.API.generateModelController(model, writeStream);
						});
					});

					return result;
				})
				.then(function() {
					done();
				})
				.done();
		}
		else if(this.target == 'scripts') {
			app.controllers.setup(basePath)
				.then(function() {
					return app.models.setup(basePath);
				})
				.then(function() {
					setImmediate(function() {
						return mkdir(path.join(basePath, 'public'))
							.then(function() {
								return mkdir(path.join(basePath, 'public', 'scripts'));
							})
							.then(function() {
								var writeStream = fs.createWriteStream(path.join(basePath, 'public', 'scripts', 'fire.js'));

								app.bridge.generate(writeStream)
									.then(function() {
										done();
									})
									.done();
							});
					});
				})
				.done();
		}
		else {
			done();
		}
	});

	grunt.registerTask('build', ['less', 'jade', 'firebuild', 'uglify']);
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-jade');
	return gruntConfig;
};
<commit_msg>enables source maps in less and js tasks<commit_after>exports = module.exports = new Build();

var path = require('path');
var fs = require('fs');
var Q = require('q');

function mkdir(dirPath) {
	var defer = Q.defer();
	fs.mkdir(dirPath, function() {
		defer.resolve(true);
	});
	return defer.promise;
}

function unloadModules(basePath) {
	var name = require.resolve('fire');
	if(typeof require.cache[name] != 'undefined') {
		delete require.cache[name];
	}

	var moduleName = require.resolve(path.join(basePath, 'index.js'));
	if(typeof require.cache[moduleName] != 'undefined') {
		delete require.cache[moduleName];
	}

	Object.keys(require.cache).forEach(function(requireName) {
		if(requireName.indexOf(basePath) === 0) {
			delete require.cache[requireName];
		}
	});
}

function loadApp(basePath) {
	unloadModules(basePath);

	var fire = require('../../../');
	fire.disabled = true;
	fire.appsMap = {};

	require(path.join(basePath, 'index.js'));

	return fire.app(Object.keys(fire.appsMap)[0]);
}

function Build() {

}

Build.prototype.extendConfig = function(gruntConfig, grunt) {
	if(!gruntConfig.firebuild) {
		gruntConfig.firebuild = {};
	}

	gruntConfig.firebuild.migrations = {};
	gruntConfig.firebuild.api = {};
	gruntConfig.firebuild.scripts = {};

	var optionsApp = loadApp(process.cwd());

	gruntConfig.less = {
		options: {
			sourceMap: true
		},
		src: {
			expand: true,
			src: ['./styles/*.less'],
			dest: 'public/',
			ext: '.css'
		}
	};

	gruntConfig.jade = {
		compile: {
			options: {
				data: optionsApp._options
			},
			files: [{
				expand: true,
				src: 'templates/**/*.jade',
				dest: 'public/',
				ext: '.html'
			}]
		}
	};

	gruntConfig.uglify = {
		options: {
			sourceMap: true
		},
		build: {
			src: 'public/scripts/fire.js',
			dest: 'public/scripts/fire.min.js'
		}
	};

	if(!gruntConfig.release) {
		gruntConfig.release = {};
	}

	gruntConfig.release.migrate = {};

	if(!gruntConfig.run) {
		gruntConfig.run = {};
	}

	grunt.registerMultiTask('release', function(version) {
		var dotenv = require('dotenv');
		dotenv.load();

		var Migrations = require('../migrations');

		var basePath = process.cwd();
		var app = loadApp(basePath);

		app.models.forEach(function(model, modelName) {
			delete app.models.internals[modelName];
			delete app.models[modelName];
		});

		var models = app.models; //new Models(app);
		var migrations = new Migrations();

		var targetVersion = version;

		var done = this.async();

		// Set-up without reading any of the models
		// We will create the models based on all migrations

		models.setup(null)
			.then(function() {
				return migrations.setup(path.join(basePath, '_migrations'), models);
			})
			.then(function() {
				if(migrations._.length === 0) {
					throw new Error('There are 0 migration files. Did you run `fire generate migrations`?');
				}
			})
			.then(function() {
				// Let's find which database version we're at
				return migrations.currentVersion();
			})
			.then(function(currentVersion) {
				if(!targetVersion) {
					targetVersion = migrations._[migrations._.length - 1].version;
				}

				if(targetVersion == currentVersion) {
					console.log('*** Database is up-to-date.');
				}
				else {
					console.log('*** Migrating from `' + currentVersion + '` to `' + targetVersion + '`.');

					return migrations.migrate(currentVersion, targetVersion)
						.then(function() {
							return migrations.currentVersion();
						})
						.then(function(newVersion) {
							if(newVersion == targetVersion) {
								//everything went alright
								console.log('*** Migration successful to `' + targetVersion + '`.');
							}
							else {
								throw new Error('Database version after migration `' + newVersion + '` does not match target version `' + targetVersion + '`.');
							}
						});
				}
			})
			.then(function() {
				done();
			})
			.catch(function(error) {
				console.log(error.message);
				console.log(error.stack);

				throw error;
			})
			.done();
	});

	grunt.registerMultiTask('firebuild', function() {
		var done = this.async();
		var basePath = process.cwd();

		var app = loadApp(basePath);

		if(this.target == 'migrations') {
			mkdir(path.join(basePath, '_migrations'))
				.then(function() {
					var Generate = require('../migrations/generate');
					var generate = new Generate(app, basePath);
					generate.delegate = {
						addMigration: function(fileName, stream) {
							var writeStream = fs.createWriteStream(path.join(basePath, '_migrations', fileName));
							stream.pipe(writeStream);

							writeStream.once('finish', function() {
								done();
							});
						}
					};

					return generate.createMigrations(true);
				})
				.then(function(result) {
					if(!result) {
						// If the result is false, there are no migrations so we'll call done.
						done();
					}
				})
				.done();
		}
		else if(this.target == 'api') {
			app.controllers.setup(basePath)
				.then(function() {
					return app.models.setup(basePath);
				})
				.then(function() {
					var defer = Q.defer();

					setImmediate(function() {
						fs.mkdir(path.join(basePath, '_api'), function() {
							defer.resolve();
						});
					});

					return defer.promise;
				})
				.then(function() {
					var result = Q.when(true);

					app.models.forEach(function(model) {
						result = result.then(function() {
							var writeStream = fs.createWriteStream(path.join(basePath, '_api', model.getFileName() + '.js'));
							return app.API.generateModelController(model, writeStream);
						});
					});

					return result;
				})
				.then(function() {
					done();
				})
				.done();
		}
		else if(this.target == 'scripts') {
			app.controllers.setup(basePath)
				.then(function() {
					return app.models.setup(basePath);
				})
				.then(function() {
					setImmediate(function() {
						return mkdir(path.join(basePath, 'public'))
							.then(function() {
								return mkdir(path.join(basePath, 'public', 'scripts'));
							})
							.then(function() {
								var writeStream = fs.createWriteStream(path.join(basePath, 'public', 'scripts', 'fire.js'));

								app.bridge.generate(writeStream)
									.then(function() {
										done();
									})
									.done();
							});
					});
				})
				.done();
		}
		else {
			done();
		}
	});

	grunt.registerTask('build', ['less', 'jade', 'firebuild', 'uglify']);
	grunt.loadNpmTasks('grunt-contrib-less');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-jade');
	return gruntConfig;
};
<|endoftext|>


<commit_before>//Application Window Component Constructor
exports.ApplicationWindow = function() {

	Ti.API.log(JSON.stringify(Titanium.Platform.osname));

	var _ = require('underscore')._;

	require('date'); // This adds Date.js library, extending standard Date() object

	Ti.include('date.js');

	// TODO: use Ti.UI.iPad split view for iPad version

	var self = Ti.UI.createWindow({
		backgroundColor : '#fff',
		fullscreen : false,
		exitOnClose : true,
		top: "0dp",
		title:'Friends Events',
		navBarHidden: false,
	});

	// invoke loginView

	var loginView = require('ui/LoginView').LoginView();
	self.add(loginView);

	var headerLabel = Ti.UI.createLabel({
		text: "Friends events",
		top: "0dp",
		height: "44dp",
		textAlign:'center',
		color:"#fff",
		font: {
			fontSize: 18,
			fontWeight: "bold"
		},
		zIndex: 100,
		backgroundImage: "/images/iphone_title_bar_blue.png",
		backgroundRepeat: true,
		width: "100%",
	});

	var buttonFacebookLogout = Ti.UI.createButton({
		title: "Logout",
		top: "8dp",
		height: "29dp",
		width: "64dp",
		right: "5dp",
		color: "white",
		selectedColor: "gray",
		font: {
			fontSize: 12,
			fontWeight: "bold"
		},
		backgroundImage: "/images/iphone_title_button_blue.png",
		backgroundFocusedImage: "/images/iphone_title_button_blue_focused.png",
		backgroundSelectedImage: "/images/iphone_title_button_blue_focused.png",
		zIndex: 102
	});

	var searchBar = Ti.UI.createSearchBar({
		autocapitalization: Ti.UI.TEXT_AUTOCAPITALIZATION_NONE,
		autocorrect: false,
		hintText: "search...",
		top: "0dp",
		backgroundColor: "red"
	});

	self.add(headerLabel);
	self.add(buttonFacebookLogout);

	var tableView = Ti.UI.createTableView({
		top: "44dp",
		height: (Titanium.Platform.osname==='ipad'?"936dp":"416dp"),
		search: searchBar,
		filterAttribute : 'name',
		backgroundColor: "green",
		data : [{title:'loading...'}]
	});

	var search_value = "";

	tableView.addEventListener('click', function(e) {
		Ti.API.error("We're clicking table row")

		var eventView = require('ui/EventView').EventView(e.rowData.data, all_my_friends);
		self.add(eventView);

		Ti.API.info(JSON.stringify(e.rowData.data));
	});

	self.add(tableView);

	buttonFacebookLogout.addEventListener('click', function(e) {
		Titanium.Facebook.logout();
		loginView.show();
		tableView.hide();
	});

	var all_my_friends		= [];
	var table_data_events	= [];

	var process_events = function(e) {
		if(e.success) {

			var events_result = JSON.parse(e.result);

			for(var i = 0; i < events_result.data.length; i++) {

				// don't process any events from the past
				//if((Date.today()-Date.parse(events_result.data[i].start_time))>0) {
				//	continue;
				//}

				var table_row_data = {
					data : events_result.data[i],
					hasChild : true,
					className : "event_layout",
					name : events_result.data[i].name
				};

				var row = Ti.UI.createTableViewRow(table_row_data);

				var label = Ti.UI.createLabel({
					left : "50dp",
					top  : "0dp",
					height: "44dp",
					width: Ti.UI.FILL,
					text : events_result.data[i].name,
					font : {
						fontSize : 12
					}
				});

				var image = Ti.UI.createImageView({
					top : "0dp",
					left : "0dp",
					width : "44dp",
					height : "44dp",
					image : "https://graph.facebook.com/" + (events_result.data[i].id || 0) + "/picture?type=small&access_token=" + Ti.Facebook.accessToken
				});

				row.add(label);
				row.add(image);

				row.addEventListener('click', function(e) {
					Ti.API.error("We're clicking table row via second");

					var eventView = require('ui/EventView').EventView(e.rowData.data, all_my_friends);
					self.add(eventView);

					Ti.API.info(JSON.stringify(e.rowData.data));
				});

				table_data_events.push(row);
			}

			// remove duplicates and sort table
			table_data_events = _(table_data_events).chain().uniq(false, function(obj) {
				return obj.data.id;
			}).sortBy( function(obj) {
				return obj.data.start_time;
			}).value();

			tableView.setData(table_data_events);

		} else {
			if(e.error) {
				Ti.API.info(e.error);
			} else {
				Ti.API.info("Unknown result");
			}
		}
	};

	var populate_events = function() {

		tableView.setData([]);

		Ti.Facebook.requestWithGraphPath('me/friends', {"limit":0}, 'GET', function(e) {
			if(e.success) {
				var result = JSON.parse(e.result);
				all_my_friends = result.data;

				Ti.API.info('Friends found: '+ result.data.length);

				for (var i = 0; i < result.data.length; i++) {

					var friend = result.data[i];

					// TODO: cache all in json-based local storage
					// TODO: filter by where your friends are going or NOT going ;)

					Ti.Facebook.requestWithGraphPath(''+friend.id+'/events', {"limit":0}, 'GET', process_events);
				}

			} else {
				if(e.error) {
					Ti.API.info(e.error);
				} else {
					Ti.API.info("Unknown result");
				}
			}
		});
	};

	if(Ti.Facebook.loggedIn) {
		loginView.hide();
		tableView.show();
		populate_events();
	}

	Ti.Facebook.appid = '187742787964643';
	Ti.Facebook.permissions = [
		'user_events',
		'friends_events',
		'rsvp_event',
		'publish_checkins'
	];

	// Permissions your app needs
	Ti.Facebook.addEventListener('login', function(e) {
		if(e.success) {
			Ti.API.info('Logged In');
			loginView.hide();
			tableView.show();
			populate_events();

			Ti.Facebook.requestWithGraphPath('me', {}, 'GET', function(e) {
				if(e.success) {
					Ti.API.info(e.result);
					// Ti.API.info('access_token = ', Titanium.Facebook.getAccessToken());
				} else if(e.error) {
					Ti.API.info(e.error);
				} else {
					Ti.API.info('Unknown response');
				}
			});
		} else if(e.error) {
			Ti.API.info(e.error);
		} else if(e.cancelled) {
			Ti.API.info("Cancelled");
		}
	});

	return self;

};
<commit_msg>removed require/Ti.include duplication<commit_after>//Application Window Component Constructor
exports.ApplicationWindow = function() {

	Ti.API.log(JSON.stringify(Titanium.Platform.osname));

	var _ = require('underscore')._;

	require('date'); // This adds Date.js library, extending standard Date() object

	// Ti.include('date.js');

	// TODO: use Ti.UI.iPad split view for iPad version

	var self = Ti.UI.createWindow({
		backgroundColor : '#fff',
		fullscreen : false,
		exitOnClose : true,
		top: "0dp",
		title:'Friends Events',
		navBarHidden: false,
	});

	// invoke loginView

	var loginView = require('ui/LoginView').LoginView();
	self.add(loginView);

	var headerLabel = Ti.UI.createLabel({
		text: "Friends events",
		top: "0dp",
		height: "44dp",
		textAlign:'center',
		color:"#fff",
		font: {
			fontSize: 18,
			fontWeight: "bold"
		},
		zIndex: 100,
		backgroundImage: "/images/iphone_title_bar_blue.png",
		backgroundRepeat: true,
		width: "100%",
	});

	var buttonFacebookLogout = Ti.UI.createButton({
		title: "Logout",
		top: "8dp",
		height: "29dp",
		width: "64dp",
		right: "5dp",
		color: "white",
		selectedColor: "gray",
		font: {
			fontSize: 12,
			fontWeight: "bold"
		},
		backgroundImage: "/images/iphone_title_button_blue.png",
		backgroundFocusedImage: "/images/iphone_title_button_blue_focused.png",
		backgroundSelectedImage: "/images/iphone_title_button_blue_focused.png",
		zIndex: 102
	});

	var searchBar = Ti.UI.createSearchBar({
		autocapitalization: Ti.UI.TEXT_AUTOCAPITALIZATION_NONE,
		autocorrect: false,
		hintText: "search...",
		top: "0dp",
		backgroundColor: "red"
	});

	self.add(headerLabel);
	self.add(buttonFacebookLogout);

	var tableView = Ti.UI.createTableView({
		top: "44dp",
		height: (Titanium.Platform.osname==='ipad'?"936dp":"416dp"),
		search: searchBar,
		filterAttribute : 'name',
		backgroundColor: "green",
		data : [{title:'loading...'}]
	});

	var search_value = "";

	tableView.addEventListener('click', function(e) {
		Ti.API.error("We're clicking table row")

		var eventView = require('ui/EventView').EventView(e.rowData.data, all_my_friends);
		self.add(eventView);

		Ti.API.info(JSON.stringify(e.rowData.data));
	});

	self.add(tableView);

	buttonFacebookLogout.addEventListener('click', function(e) {
		Titanium.Facebook.logout();
		loginView.show();
		tableView.hide();
	});

	var all_my_friends		= [];
	var table_data_events	= [];

	var process_events = function(e) {
		if(e.success) {

			var events_result = JSON.parse(e.result);

			for(var i = 0; i < events_result.data.length; i++) {

				// don't process any events from the past
				//if((Date.today()-Date.parse(events_result.data[i].start_time))>0) {
				//	continue;
				//}

				var table_row_data = {
					data : events_result.data[i],
					hasChild : true,
					className : "event_layout",
					name : events_result.data[i].name
				};

				var row = Ti.UI.createTableViewRow(table_row_data);

				var label = Ti.UI.createLabel({
					left : "50dp",
					top  : "0dp",
					height: "44dp",
					width: Ti.UI.FILL,
					text : events_result.data[i].name,
					font : {
						fontSize : 12
					}
				});

				var image = Ti.UI.createImageView({
					top : "0dp",
					left : "0dp",
					width : "44dp",
					height : "44dp",
					image : "https://graph.facebook.com/" + (events_result.data[i].id || 0) + "/picture?type=small&access_token=" + Ti.Facebook.accessToken
				});

				row.add(label);
				row.add(image);

				row.addEventListener('click', function(e) {
					Ti.API.error("We're clicking table row via second");

					var eventView = require('ui/EventView').EventView(e.rowData.data, all_my_friends);
					self.add(eventView);

					Ti.API.info(JSON.stringify(e.rowData.data));
				});

				table_data_events.push(row);
			}

			// remove duplicates and sort table
			table_data_events = _(table_data_events).chain().uniq(false, function(obj) {
				return obj.data.id;
			}).sortBy( function(obj) {
				return obj.data.start_time;
			}).value();

			tableView.setData(table_data_events);

		} else {
			if(e.error) {
				Ti.API.info(e.error);
			} else {
				Ti.API.info("Unknown result");
			}
		}
	};

	var populate_events = function() {

		tableView.setData([]);

		Ti.Facebook.requestWithGraphPath('me/friends', {"limit":0}, 'GET', function(e) {
			if(e.success) {
				var result = JSON.parse(e.result);
				all_my_friends = result.data;

				Ti.API.info('Friends found: '+ result.data.length);

				for (var i = 0; i < result.data.length; i++) {

					var friend = result.data[i];

					// TODO: cache all in json-based local storage
					// TODO: filter by where your friends are going or NOT going ;)

					Ti.Facebook.requestWithGraphPath(''+friend.id+'/events', {"limit":0}, 'GET', process_events);
				}

			} else {
				if(e.error) {
					Ti.API.info(e.error);
				} else {
					Ti.API.info("Unknown result");
				}
			}
		});
	};

	if(Ti.Facebook.loggedIn) {
		loginView.hide();
		tableView.show();
		populate_events();
	}

	Ti.Facebook.appid = '187742787964643';
	Ti.Facebook.permissions = [
		'user_events',
		'friends_events',
		'rsvp_event',
		'publish_checkins'
	];

	// Permissions your app needs
	Ti.Facebook.addEventListener('login', function(e) {
		if(e.success) {
			Ti.API.info('Logged In');
			loginView.hide();
			tableView.show();
			populate_events();

			Ti.Facebook.requestWithGraphPath('me', {}, 'GET', function(e) {
				if(e.success) {
					Ti.API.info(e.result);
					// Ti.API.info('access_token = ', Titanium.Facebook.getAccessToken());
				} else if(e.error) {
					Ti.API.info(e.error);
				} else {
					Ti.API.info('Unknown response');
				}
			});
		} else if(e.error) {
			Ti.API.info(e.error);
		} else if(e.cancelled) {
			Ti.API.info("Cancelled");
		}
	});

	return self;

};
<|endoftext|>


<commit_before>(function (requirejs, require, define) {
define('WordCloudMain', ['logme'], function (logme) {

    var hash = 0;

WordCloudMain.prototype = {

'submitAnswer': function () {
    var _this, data;

    data = {
        'student_words': []
    };

    _this = this;

    this.wordCloudEl.find('input.input-cloud').each(function(index, value){
        data.student_words.push($(value).val());
    });

    // Send the data to the server as an AJAX request. Attach a callback that will
    // be fired on server's response.
    $.postWithPrefix(
        _this.ajax_url + '/' + 'submit', $.param(data),
        function (response) {
            if (
                (response.hasOwnProperty('status') !== true) ||
                (typeof response.status !== 'string') ||
                (response.status.toLowerCase() !== 'success')) {

                return;
            }
            _this.showWordCloud(response);
        }
    );

}, // End-of: 'submitAnswer': function (answer, answerEl) {

'showWordCloud': function(response){
    var words,
        _this = this,
        fill = d3.scale.category20(),
        maxSize, minSize;

    this.wordCloudEl.find('#input-cloud-section').hide();

    words = response.top_words;

    maxSize = 0;
    minSize = 10000;

    $.each(words, function (index, word) {
        if (word.size > maxSize) {
            maxSize = word.size;
        }
        if (word.size < minSize) {
            minSize = word.size;
        }
    });

    d3.layout.cloud().size([500, 500])
        .words(words)
        .rotate(function () {
            return ~~(Math.random() * 2) * 90;
        })
        .font('Impact')
        .fontSize(function (d) {
            var size;

            size = (d.size / maxSize) * 140;

            if (size < 20) {
                return 0;
            }

            return size;
        })
        .on('end', draw)
        .start();

    // End of executable code.
    return;

    function draw(words) {
        var el;

        $('#word_cloud_d3_' + _this.hash).remove();

        el = $(
            '

'
        );
        _this.wordCloudEl.append(el);

        d3.select('#word_cloud_d3_' + _this.hash).append('svg')
            .attr('width', 500)
            .attr('height', 500)
            .attr('id', 'word_cloud_d3_' + _this.hash)
            .append('g')
            .attr('transform', 'translate(190,250)')
            .selectAll('text')
            .data(words)
            .enter().append('text')
            .style('font-size', function (d) {
                return d.size + 'px';
            })
            .style('font-family', 'Impact')
            .style('fill', function (d, i) {
                return fill(i);
            })
            .attr('text-anchor', 'middle')
            .attr('transform', function (d) {
                return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
            })
            .text(function (d) {
                return d.text;
            });
    }
}

}; // End-of: WordCloudMain.prototype = {

return WordCloudMain;

function WordCloudMain(el) {
    var _this;

    this.wordCloudEl = $(el).find('.word_cloud');
    if (this.wordCloudEl.length !== 1) {
        // We require one question DOM element.
        logme('ERROR: WordCloudMain constructor requires one word cloud DOM element.');

        return;
    }

    hash += 1;
    this.hash = hash;
    this.wordCloudEl.addClass('word_cloud_d3_' + this.hash);

    this.configJson = null;
    try {
        this.configJson = JSON.parse(this.wordCloudEl.find('.word_cloud_div').html());
    } catch (err) {
        logme('ERROR: Incorrect JSON config was given.');
        logme(err.message);

        return;
    }

    if (this.configJson.submitted) {
        this.showWordCloud(this.configJson);

        return;
    }

    this.inputSaveEl = $(el).find('input.save');

    // Get the URL to which we will post the users words.
    this.ajax_url = this.wordCloudEl.data('ajax-url');

    _this = this;
    this.inputSaveEl.on('click', function () {
        _this.submitAnswer();
    });

} // End-of: function WordCloudMain(el) {

}); // End-of: define('WordCloudMain', ['logme'], function (logme) {

// End-of: (function (requirejs, require, define) {
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
<commit_msg>Change some code styling. Added statistics display. Minor tweaks.<commit_after>(function (requirejs, require, define) {
define('WordCloudMain', ['logme'], function (logme) {

    var hash = 0;

WordCloudMain.prototype = {

'submitAnswer': function () {
    var _this = this,
        data = {
            'student_words': []
        };

    this.wordCloudEl.find('input.input-cloud').each(function(index, value){
        data.student_words.push($(value).val());
    });

    // Send the data to the server as an AJAX request. Attach a callback that will
    // be fired on server's response.
    $.postWithPrefix(
        _this.ajax_url + '/' + 'submit', $.param(data),
        function (response) {
            if (response.status !== 'success') {
                logme('ERROR: ' + response.error);

                return;
            }

            _this.showWordCloud(response);
        }
    );

}, // End-of: 'submitAnswer': function (answer, answerEl) {

'showWordCloud': function(response){
    var words,
        _this = this,
        fill = d3.scale.category20(),
        maxSize, minSize;

    this.wordCloudEl.find('#input-cloud-section').hide();

    console.log('response: ', response);

    words = response.top_words;

    maxSize = 0;
    minSize = 10000;

    $.each(words, function (index, word) {
        if (word.size > maxSize) {
            maxSize = word.size;
        }
        if (word.size < minSize) {
            minSize = word.size;
        }
    });

    d3.layout.cloud().size([500, 500])
        .words(words)
        .rotate(function () {
            return ~~(Math.random() * 2) * 90;
        })
        .font('Impact')
        .fontSize(function (d) {
            var size;

            size = (d.size / maxSize) * 100;

            if (size < 20) {
                return 0;
            }

            return size;
        })
        .on('end', draw)
        .start();

    // End of executable code.
    return;

    function draw(words) {
        var el, firstWord = false;

        $('#word_cloud_d3_' + _this.hash).remove();

        el = $(
            '

'
        );
        el.append('
Your words
');
        $.each(response.student_words, function (index, value) {
            if (firstWord === false) {
                firstWord = true;
            } else {
                el.append(', ');
            }

            el.append(index + ': ' + (100.0 * (value / response.total_count)) + ' %');
        });
        el.append('

Overall number of words: ' + response.total_count + '

');
        _this.wordCloudEl.append(el);

        d3.select('#word_cloud_d3_' + _this.hash).append('svg')
            .attr('width', 500)
            .attr('height', 500)
            .append('g')
            .attr('transform', 'translate(190,250)')
            .selectAll('text')
            .data(words)
            .enter().append('text')
            .style('font-size', function (d) {
                return d.size + 'px';
            })
            .style('font-family', 'Impact')
            .style('fill', function (d, i) {
                return fill(i);
            })
            .attr('text-anchor', 'middle')
            .attr('transform', function (d) {
                return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
            })
            .text(function (d) {
                return d.text;
            });
    }
}

}; // End-of: WordCloudMain.prototype = {

return WordCloudMain;

function WordCloudMain(el) {
    var _this = this;

    this.wordCloudEl = $(el).find('.word_cloud');
    if (this.wordCloudEl.length !== 1) {
        // We require one question DOM element.
        logme('ERROR: WordCloudMain constructor requires one word cloud DOM element.');

        return;
    }

    // Later on used to create a unique DOM element.
    hash += 1;
    this.hash = hash;

    this.configJson = null;
    try {
        this.configJson = JSON.parse(this.wordCloudEl.find('.word_cloud_div').html());
    } catch (err) {
        logme('ERROR: Incorrect JSON config was given.');
        logme(err.message);

        return;
    }

    if (this.configJson.submitted) {
        this.showWordCloud(this.configJson);

        return;
    }

    this.inputSaveEl = $(el).find('input.save');

    // Get the URL to which we will post the users words.
    this.ajax_url = this.wordCloudEl.data('ajax-url');

    this.inputSaveEl.on('click', function () {
        _this.submitAnswer();
    });

} // End-of: function WordCloudMain(el) {

}); // End-of: define('WordCloudMain', ['logme'], function (logme) {

// End-of: (function (requirejs, require, define) {
}(RequireJS.requirejs, RequireJS.require, RequireJS.define));
<|endoftext|>


<commit_before>(function($, Array) {
	if (!('indexOf' in Array.prototype)) {
		Array.prototype.indexOf= function(find, i /*opt*/) {
			if (i===undefined) i= 0;
			if (i<0) i+= this.length;
			if (i<0) i= 0;
			for (var n= this.length; i<n; i++)
				if (i in this && this[i]===find)
					return i;
			return -1;
		};
	}

	$.widget("ui.SelectMultiple", {
		options: {
			sels: {
				self:	".select_multiple",
				list:	"ul",
				item:	"li"
			},
			html: {
				wrapper:	"

",
				list:		"

",
				item:		"

"
			},
			classes: {
				active: "active"
			}
		},

		_create: function() {
			var instance = this;

			this.select = this.element;
			var width = this.element.outerWidth();
			var height = this.element.outerHeight();
			this.select.wrap(this.options.html.wrapper);
			this.element = this.select.parent();
			this.element.width(width);
			this.select.hide();
			this.all_options = this.select.find("option");
			this.element.append(this.options.html.list);

			this.list = this.element.find(this.options.sels.list);
			this.list.width(width).height(height);
			this.all_options.each(function() {
				instance.list.append(instance.options.html.item);
				var item = instance.list.find(instance.options.sels.item).last();
				item.text($(this).text());
			});
			this.all_items = this.list.find(this.options.sels.item);
			this.scrolled_to_index = 0;

			this.init();
		},

		init: function() {
			var instance = this;
			this.current_index = this.select.find("option:selected").first().index();
			this.select.find("option:selected").each(function() {
				var index = $(this).index();
				instance.all_items.eq(index).addClass(instance.options.classes.active);
			});
			this.store_active();

			var count = 0;
			this.all_items.click(function(event) {
				if(!instance.state_focus) {
					return;
				}

				count = 0;
				var index = $(this).index();
				if(event.shiftKey) {
					count = index - instance.current_index;
					instance.selection(instance.current_index, count);
					instance.store_active();
				} else if(event.ctrlKey) {
					instance.toggle(index);
					instance.current_index = instance.select.find("option:selected").first().index();
					instance.store_active();
				} else {
					var change = false;
					instance.select.find("option:selected").each(function() {
						if(index != $(this).index()) {
							instance.deactivate($(this).index());
							change = true;
						}
					});
					change = instance.activate(index) || change;
					if(change) {
						instance.select.trigger("change");
					}
					instance.current_index = index;
					instance.store_active();
				}
			}).bind("selectstart dragstart", function(event) {
				event.preventDefault();
				return false;
			});

			$(document).bind("keydown", "shift+up", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count--;
				if(instance.current_index + count >= instance.all_items.size()) {
					count = instance.all_items.size() - instance.current_index - 1;
				} else if(instance.current_index + count < 0) {
					count = - instance.current_index;
				}
				var change = instance.selection(instance.current_index, count, true);
				change = instance.restore_active() || change;
				instance.scroll_list_to(instance.current_index + count);
				if(change) {
					instance.select.trigger("change");
				}
			});
			$(document).bind("keydown", "shift+down", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count++;
				if(instance.current_index + count >= instance.all_items.size()) {
					count = instance.all_items.size() - instance.current_index - 1;
				} else if(instance.current_index + count < 0) {
					count = - instance.current_index;
				}
				var change = instance.selection(instance.current_index, count, true);
				change = instance.restore_active() || change;
				instance.scroll_list_to(instance.current_index + count);
				if(change) {
					instance.select.trigger("change");
				}
			});
			$(document).bind("keydown", "up", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count = 0;
				instance.current_index--;
				if(instance.current_index >= instance.all_items.size()) {
					instance.current_index = instance.all_items.size() - 1;
				} else if(instance.current_index < 0) {
					instance.current_index = 0;
				}
				instance.selection(instance.current_index, 0);
				instance.scroll_list_to(instance.current_index);
				instance.store_active();
			});
			$(document).bind("keydown", "down", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count = 0;
				instance.current_index++;
				if(instance.current_index >= instance.all_items.size()) {
					instance.current_index = instance.all_items.size() - 1;
				} else if(instance.current_index < 0) {
					instance.current_index = 0;
				}
				instance.selection(instance.current_index, 0);
				instance.scroll_list_to(instance.current_index);
				instance.store_active();
			});

			this.blur();
		},

		focus: function() {
			if(this.state_focus) {
				return;
			}
			this.state_focus = true;

			var instance = this;
			var focus_bind = function(event) {
				var element = $(event.target).closest(instance.options.sels.self);
				if(element.size() == 0 || element.get(0) != instance.element.get(0)) {
					instance.blur();
				} else {
					$("html").one("click", focus_bind);
				}
			};
			$("html").one("click", focus_bind);
			$("*").one("focus", function() {
				instance.blur();
			});
		},

		blur: function() {
			this.state_focus = false;

			var instance = this;
			this.element.one("click", function(event) {
				instance.focus();
				$(event.target).trigger("click");
			});
		},

		selection: function(index, count, store) {
			var size = this.all_items.size();
			var from = Math.min(index, index + count);
			var to = Math.max(index, index + count);
			var change = false;
			for(var i = 0; i < size; i++) {
				if(i >= from && i <= to) {
					if(this.activate(i)) {
						change = true;
					}
				} else {
					if(this.deactivate(i, store)) {
						change = true;
					}
				}
			}
			return change;
		},

		activate: function(index) {
			var option = this.all_options.eq(index);
			var li = this.all_items.eq(index);
			if(!li.hasClass(this.options.classes.active)) {
				option.attr("selected", "selected");
				li.addClass(this.options.classes.active);
				option.trigger("click");
				return true;
			}
			return false;
		},

		deactivate: function(index, store) {
			if(store && this.list_active.indexOf(index) != -1) {
				return false;
			}
			var option = this.all_options.eq(index);
			var li = this.all_items.eq(index);
			if(li.hasClass(this.options.classes.active)) {
				li.removeClass(this.options.classes.active);
				option.removeAttr("selected");
				option.trigger("click");
				return true;
			}
			return false;
		},

		toggle: function(index) {
			var option = this.all_options.eq(index);
			var li = this.all_items.eq(index);
			if(li.hasClass(this.options.classes.active)) {
				option.removeAttr("selected");
				li.removeClass(this.options.classes.active);
				this.current_index = this.select.find("option:selected").last().index();
			} else {
				option.attr("selected", "selected");
				li.addClass(this.options.classes.active);
				this.current_index = index;
			}
			option.trigger("click");
			this.select.trigger("change");
		},

		scroll_list_to: function(index) {
			var current = this.all_items.eq(index);
			//if current is not in visible part
			if (current.position().top < 0) {
				this.scrolled_to_index = index;
				this.list.scrollTo(this.all_items.eq(this.scrolled_to_index));
			} else if(current.position().top + current.height() > this.list.height()) {
				this.scrolled_to_index++;
				if(this.scrolled_to_index >= this.all_items.size()) {
					this.scrolled_to_index = this.all_items.size() - 1;
				}
				this.list.scrollTo(this.all_items.eq(this.scrolled_to_index));
			}
		},

		store_active: function() {
			var instance = this;
			this.list_active = [];
			this.select.find("option:selected").each(function() {
				instance.list_active.push($(this).index());
			});
		},

		restore_active: function() {
			var change = false;
			for(var i = 0; i < this.list_active.length; i++) {
				if(this.activate(this.list_active[i])) {
					change = true;
				}
			}
			return change;
		},

		destroy: function() {
			this.element.unbind("click");
			this.list.remove();
			this.select.unwrap();
			this.select.show();
			$.Widget.prototype.destroy.call(this);
		}
	});
})(jQuery, Array);
<commit_msg>fix autoscroll<commit_after>(function($, Array) {
	if (!('indexOf' in Array.prototype)) {
		Array.prototype.indexOf= function(find, i /*opt*/) {
			if (i===undefined) i= 0;
			if (i<0) i+= this.length;
			if (i<0) i= 0;
			for (var n= this.length; i<n; i++)
				if (i in this && this[i]===find)
					return i;
			return -1;
		};
	}

	$.widget("ui.SelectMultiple", {
		options: {
			sels: {
				self:	".select_multiple",
				list:	"ul",
				item:	"li"
			},
			html: {
				wrapper:	"

",
				list:		"

",
				item:		"

"
			},
			classes: {
				active: "active"
			}
		},

		_create: function() {
			var instance = this;

			this.select = this.element;
			var width = this.element.outerWidth();
			var height = this.element.outerHeight();
			this.select.wrap(this.options.html.wrapper);
			this.element = this.select.parent();
			this.element.width(width);
			this.select.hide();
			this.all_options = this.select.find("option");
			this.element.append(this.options.html.list);

			this.list = this.element.find(this.options.sels.list);
			this.list.width(width).height(height);
			this.all_options.each(function() {
				instance.list.append(instance.options.html.item);
				var item = instance.list.find(instance.options.sels.item).last();
				item.text($(this).text());
			});
			this.all_items = this.list.find(this.options.sels.item);

			this.init();
		},

		init: function() {
			var instance = this;
			this.current_index = this.select.find("option:selected").first().index();
			this.select.find("option:selected").each(function() {
				var index = $(this).index();
				instance.all_items.eq(index).addClass(instance.options.classes.active);
			});
			this.store_active();

			var count = 0;
			this.all_items.click(function(event) {
				if(!instance.state_focus) {
					return;
				}

				count = 0;
				var index = $(this).index();
				if(event.shiftKey) {
					count = index - instance.current_index;
					instance.selection(instance.current_index, count);
					instance.scroll_list_to(instance.current_index + count);
					instance.store_active();
				} else if(event.ctrlKey) {
					instance.toggle(index);
					instance.current_index = instance.select.find("option:selected").first().index();
					instance.scroll_list_to(index);
					instance.store_active();
				} else {
					var change = false;
					instance.select.find("option:selected").each(function() {
						if(index != $(this).index()) {
							instance.deactivate($(this).index());
							change = true;
						}
					});
					change = instance.activate(index) || change;
					if(change) {
						instance.select.trigger("change");
					}
					instance.current_index = index;
					instance.scroll_list_to(instance.current_index);
					instance.store_active();
				}
			}).bind("selectstart dragstart", function(event) {
				event.preventDefault();
				return false;
			});

			$(document).bind("keydown", "shift+up", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count--;
				if(instance.current_index + count >= instance.all_items.size()) {
					count = instance.all_items.size() - instance.current_index - 1;
				} else if(instance.current_index + count < 0) {
					count = - instance.current_index;
				}
				var change = instance.selection(instance.current_index, count, true);
				change = instance.restore_active() || change;
				instance.scroll_list_to(instance.current_index + count);
				if(change) {
					instance.select.trigger("change");
				}
			});
			$(document).bind("keydown", "shift+down", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count++;
				if(instance.current_index + count >= instance.all_items.size()) {
					count = instance.all_items.size() - instance.current_index - 1;
				} else if(instance.current_index + count < 0) {
					count = - instance.current_index;
				}
				var change = instance.selection(instance.current_index, count, true);
				change = instance.restore_active() || change;
				instance.scroll_list_to(instance.current_index + count);
				if(change) {
					instance.select.trigger("change");
				}
			});
			$(document).bind("keydown", "up", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count = 0;
				instance.current_index--;
				if(instance.current_index >= instance.all_items.size()) {
					instance.current_index = instance.all_items.size() - 1;
				} else if(instance.current_index < 0) {
					instance.current_index = 0;
				}
				instance.selection(instance.current_index, 0);
				instance.scroll_list_to(instance.current_index);
				instance.store_active();
			});
			$(document).bind("keydown", "down", function(event) {
				event.preventDefault();
				if(!instance.state_focus) {
					return;
				}

				count = 0;
				instance.current_index++;
				if(instance.current_index >= instance.all_items.size()) {
					instance.current_index = instance.all_items.size() - 1;
				} else if(instance.current_index < 0) {
					instance.current_index = 0;
				}
				instance.selection(instance.current_index, 0);
				instance.scroll_list_to(instance.current_index);
				instance.store_active();
			});

			this.blur();
		},

		focus: function() {
			if(this.state_focus) {
				return;
			}
			this.state_focus = true;

			var instance = this;
			var focus_bind = function(event) {
				var element = $(event.target).closest(instance.options.sels.self);
				if(element.size() == 0 || element.get(0) != instance.element.get(0)) {
					instance.blur();
				} else {
					$("html").one("click", focus_bind);
				}
			};
			$("html").one("click", focus_bind);
			$("*").one("focus", function() {
				instance.blur();
			});
		},

		blur: function() {
			this.state_focus = false;

			var instance = this;
			this.element.one("click", function(event) {
				instance.focus();
				$(event.target).trigger("click");
			});
		},

		selection: function(index, count, store) {
			var size = this.all_items.size();
			var from = Math.min(index, index + count);
			var to = Math.max(index, index + count);
			var change = false;
			for(var i = 0; i < size; i++) {
				if(i >= from && i <= to) {
					if(this.activate(i)) {
						change = true;
					}
				} else {
					if(this.deactivate(i, store)) {
						change = true;
					}
				}
			}
			return change;
		},

		activate: function(index) {
			var option = this.all_options.eq(index);
			var li = this.all_items.eq(index);
			if(!li.hasClass(this.options.classes.active)) {
				option.attr("selected", "selected");
				li.addClass(this.options.classes.active);
				option.trigger("click");
				return true;
			}
			return false;
		},

		deactivate: function(index, store) {
			if(store && this.list_active.indexOf(index) != -1) {
				return false;
			}
			var option = this.all_options.eq(index);
			var li = this.all_items.eq(index);
			if(li.hasClass(this.options.classes.active)) {
				li.removeClass(this.options.classes.active);
				option.removeAttr("selected");
				option.trigger("click");
				return true;
			}
			return false;
		},

		toggle: function(index) {
			var option = this.all_options.eq(index);
			var li = this.all_items.eq(index);
			if(li.hasClass(this.options.classes.active)) {
				option.removeAttr("selected");
				li.removeClass(this.options.classes.active);
				this.current_index = this.select.find("option:selected").last().index();
			} else {
				option.attr("selected", "selected");
				li.addClass(this.options.classes.active);
				this.current_index = index;
			}
			option.trigger("click");
			this.select.trigger("change");
		},

		scroll_list_to: function(index) {
			var current = this.all_items.eq(index);
			//if current is not in visible part
			if (current.position().top < 0) {
				this.scrolled_to_index = index;
				this.list.scrollTo(this.all_items.eq(this.scrolled_to_index));
			} else if(current.position().top + current.height() > this.list.height()) {
				var instance = this;
				var index_not_founded = true;
				this.all_items.each(function(index) {
					if(index_not_founded && $(this).position().top >= 0) {
						instance.scrolled_to_index = index;
						index_not_founded = false;
					}
				});
				this.scrolled_to_index++;
				if(this.scrolled_to_index >= this.all_items.size()) {
					this.scrolled_to_index = this.all_items.size() - 1;
				}
				this.list.scrollTo(this.all_items.eq(this.scrolled_to_index));
			}
		},

		store_active: function() {
			var instance = this;
			this.list_active = [];
			this.select.find("option:selected").each(function() {
				instance.list_active.push($(this).index());
			});
		},

		restore_active: function() {
			var change = false;
			for(var i = 0; i < this.list_active.length; i++) {
				if(this.activate(this.list_active[i])) {
					change = true;
				}
			}
			return change;
		},

		destroy: function() {
			this.element.unbind("click");
			this.list.remove();
			this.select.unwrap();
			this.select.show();
			$.Widget.prototype.destroy.call(this);
		}
	});
})(jQuery, Array);
<|endoftext|>


<commit_before>import React from 'react';

const a11yWarningIcon = (prefix, notificationType) => (
  <svg
    class={`${prefix}--${notificationType}-notification__icon`}
    width="20"
    height="20"
    xmlns="http://www.w3.org/2000/svg">
    <defs>
      <path
        d="M18.05 15.95L9.925.95a.625.625 0 0 0-1.1 0L.7 15.95a.625.625 0 0 0 0 .625.625.625 0 0 0 .55.3H17.5a.625.625 0 0 0 .55-.925z"
        id="a"
      />
      <path
        d="M.55.006h1.406v5H.55v-5zm.7 8.119a.938.938 0 1 1 0-1.875.938.938 0 0 1 0 1.875z"
        id="b"
      />
    </defs>
    <g fill="none" fill-rule="evenodd">
      <path
        d="M18.675 16.575l-8.125-15a.625.625 0 0 0-1.1 0l-8.125 15a.625.625 0 0 0 0 .625.625.625 0 0 0 .55.3h16.25a.625.625 0 0 0 .55-.925z"
        fill="#FDD13A"
      />
      <g>
        <path
          d="M9.3 6.881h1.406v5H9.3v-5zM10 15a.938.938 0 1 1 0-1.875A.938.938 0 0 1 10 15z"
          fill="#171717"
          fill-rule="nonzero"
        />
      </g>
      <path d="M0 0h20v20H0z" />
    </g>
  </svg>
);

export default a11yWarningIcon;
<commit_msg>fix(Notification): use valid prop names (#1629)<commit_after>import React from 'react';

const a11yWarningIcon = (prefix, notificationType) => (
  <svg
    className={`${prefix}--${notificationType}-notification__icon`}
    width="20"
    height="20"
    xmlns="http://www.w3.org/2000/svg">
    <defs>
      <path
        d="M18.05 15.95L9.925.95a.625.625 0 0 0-1.1 0L.7 15.95a.625.625 0 0 0 0 .625.625.625 0 0 0 .55.3H17.5a.625.625 0 0 0 .55-.925z"
        id="a"
      />
      <path
        d="M.55.006h1.406v5H.55v-5zm.7 8.119a.938.938 0 1 1 0-1.875.938.938 0 0 1 0 1.875z"
        id="b"
      />
    </defs>
    <g fill="none" fillRule="evenodd">
      <path
        d="M18.675 16.575l-8.125-15a.625.625 0 0 0-1.1 0l-8.125 15a.625.625 0 0 0 0 .625.625.625 0 0 0 .55.3h16.25a.625.625 0 0 0 .55-.925z"
        fill="#FDD13A"
      />
      <g>
        <path
          d="M9.3 6.881h1.406v5H9.3v-5zM10 15a.938.938 0 1 1 0-1.875A.938.938 0 0 1 10 15z"
          fill="#171717"
          fillRule="nonzero"
        />
      </g>
      <path d="M0 0h20v20H0z" />
    </g>
  </svg>
);

export default a11yWarningIcon;
<|endoftext|>


<commit_before>angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap"])
.directive('datetimepicker', ['$parse', function ($parse) {
  return {
    restrict: 'EA',
    require:'ngModel',
    scope: {
      ngModel: '=',
      dayFormat: "=",
      monthFormat: "=",
      yearFormat: "=",
      dayHeaderFormat: "=",
      dayTitleFormat: "=",
      monthTitleFormat: "=",
      showWeeks: "=",
      startingDay: "=",
      yearRange: "=",
      dateFormat: "=",
      minDate: "=",
      maxDate: "=",
      dateOptions: "=",
      hourStep: "=",
      minuteStep: "=",
      showMeridian: "=",
      meredians: "=",
      mousewheel: "="
    },
    template: function(elem, attrs) {
      function dashCase(name, separator){
        return name.replace(/[A-Z]/g, function(letter, pos) {
         return (pos ? '-' : '') + letter.toLowerCase();
        });
      }
      function createTimeAttr(timeAttr, dateTimeAttrOpt) {
        var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : timeAttr;
        if (attrs[dateTimeAttr]) {
          return dashCase(timeAttr) +  "=\"" + dateTimeAttr + "\" ";
        } else {
          return '';
        }
      }
      function createDateAttr(dateAttr, dateTimeAttrOpt) {
        var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : dateAttr;
        if (attrs[dateTimeAttr]) {
          return dashCase(dateAttr) + "=\"" + dateTimeAttr + "\" ";
        } else {
          return '';
        }
      }
      function createMainDateAttr(dateAttr, dateTimeAttrOpt) {
        var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : dateAttr;
        if (attrs[dateTimeAttr]) {
          return dashCase(dateAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
        } else {
          return dashCase(dateAttr);
        }
      }
      var tmpl = "
" +
        "<input type=\"text\" ng-model=\"ngModel\" " +
          createDateAttr("min", "minDate") +
          createDateAttr("max", "maxDate") +
          createDateAttr("dayFormat") +
          createDateAttr("monthFormat") +
          createDateAttr("yearFormat") +
          createDateAttr("dayHeaderFormat") +
          createDateAttr("dayTitleFormat") +
          createDateAttr("monthTitleFormat") +
          createDateAttr("showWeeks") +
          createDateAttr("startingDay") +
          createDateAttr("yearRange") +
          createDateAttr("datepickerOptions", "dateOptions") +
          createMainDateAttr("datepickerPopup", "dateFormat") +
        "/>\n" +
      "
\n" +
      "
\n" +
        "<timepicker " +
          createTimeAttr("hourStep") +
          createTimeAttr("minuteStep") +
          createTimeAttr("showMeridian") +
          createTimeAttr("meredians") +
          createTimeAttr("mousewheel") +
        "></timepicker>\n" +
      "
";
      return tmpl;
    },
    controller: ['$scope', function($scope) {
      $scope.time_change = function() {
        if (angular.isDefined($scope.ngModel) && angular.isDefined($scope.time)) {
          $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes());
        }
      }
    }],
    link: function(scope) {
      scope.$watch(function() {
          return scope.ngModel;
        }, function(ngModel) {
          scope.time = ngModel;
      });
    }
  }
}]);
<commit_msg>Added dateDisabled attribute<commit_after>angular.module('ui.bootstrap.datetimepicker', ["ui.bootstrap"])
.directive('datetimepicker', [function () {
  if (angular.version.full < '1.1.4') {
    return {
      restrict: 'EA',
      template: "
Angular 1.1.4 or above is required for datetimepicker to work correctly
"
    };
  }
  return {
    restrict: 'EA',
    require:'ngModel',
    scope: {
      ngModel: '=',
      dayFormat: "=",
      monthFormat: "=",
      yearFormat: "=",
      dayHeaderFormat: "=",
      dayTitleFormat: "=",
      monthTitleFormat: "=",
      showWeeks: "=",
      startingDay: "=",
      yearRange: "=",
      dateFormat: "=",
      minDate: "=",
      maxDate: "=",
      dateOptions: "=",
      dateDisabled: "&",
      hourStep: "=",
      minuteStep: "=",
      showMeridian: "=",
      meredians: "=",
      mousewheel: "="
    },
    template: function(elem, attrs) {
      function dashCase(name, separator){
        return name.replace(/[A-Z]/g, function(letter, pos) {
          return (pos ? '-' : '') + letter.toLowerCase();
        });
      }
      function createAttr(innerAttr, dateTimeAttrOpt) {
        var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
        if (attrs[dateTimeAttr]) {
          return dashCase(innerAttr) + "=\"" + dateTimeAttr + "\" ";
        } else {
          return '';
        }
      }
      function createFuncAttr(innerAttr, funcArgs, dateTimeAttrOpt) {
        var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
        if (attrs[dateTimeAttr]) {
          return dashCase(innerAttr) + "=\"" + dateTimeAttr + "({" + funcArgs + "})\" ";
        } else {
          return '';
        }
      }
      function createRequiredAttr(innerAttr, dateTimeAttrOpt) {
        var dateTimeAttr = angular.isDefined(dateTimeAttrOpt) ? dateTimeAttrOpt : innerAttr;
        if (attrs[dateTimeAttr]) {
          return dashCase(innerAttr) + "=\"" + attrs[dateTimeAttr] + "\" ";
        } else {
          return dashCase(innerAttr);
        }
      }
      function createAttrConcat(previousAttrs, attr) {
        return previousAttrs + createAttr.apply(null, attr)
      }
      var tmpl = "
" +
        "<input type=\"text\" ng-model=\"ngModel\" " +
          [["min", "minDate"],
           ["max", "maxDate"],
           ["dayFormat"],
           ["monthFormat"],
           ["yearFormat"],
           ["dayHeaderFormat"],
           ["dayTitleFormat"],
           ["monthTitleFormat"],
           ["showWeeks"],
           ["startingDay"],
           ["yearRange"],
           ["datepickerOptions", "dateOptions"]
          ].reduce(createAttrConcat, '') +
          createFuncAttr("dateDisabled", "date: date, mode: mode") +
          createRequiredAttr("datepickerPopup", "dateFormat") +
        "/>\n" +
      "
\n" +
      "
\n" +
        "<timepicker " +
          [["hourStep"],
           ["minuteStep"],
           ["showMeridian"],
           ["meredians"],
           ["mousewheel"]
          ].reduce(createAttrConcat, '') +
        "></timepicker>\n" +
      "
";
      return tmpl;
    },
    controller: ['$scope', function($scope) {
      $scope.time_change = function() {
        if (angular.isDefined($scope.ngModel) && angular.isDefined($scope.time)) {
          $scope.ngModel.setHours($scope.time.getHours(), $scope.time.getMinutes());
        }
      }
    }],
    link: function(scope) {
      scope.$watch(function() {
          return scope.ngModel;
        }, function(ngModel) {
          scope.time = ngModel;
      });
    }
  }
}]);
<|endoftext|>