<commit_before>/*global define*/
/*jslint white:true,browser:true*/

define([
    'kb_common/format',
], function (format) {
    'use strict';

    function pad(string, width, char, right) {
        if (!char) {
            char = '0';
        }
        if (typeof string === 'number') {
            string = String(string);
        }
        var padLen = width - string.length,
            padding = '', i;
        if (padLen <= 0) {
            return string;
        }
        for (i = 0; i < padLen; i += 1) {
            padding += char;
        }
        if (right) {
            return string + padding;
        }
        return padding + string;
    }

    function elapsedTime(value, defaultValue) {
        if (!value) {
            return defaultValue;
        }
        var temp = value,
            units = [1000, 60, 60, 24].map(function (unit) {
            var unitValue = temp % unit;
            temp = (temp - unitValue) / unit;
            return unitValue;
        });

        return [pad(units[3], 2), pad(units[2], 2), pad(units[1], 2)].join(':');
    }

    function niceElapsedTime(date) {
        if (!date) {
            return '-';
        }
        return format.niceElapsedTime(date);
    }

    function niceTime(date) {
        console.log('NICE', date);
        if (!date) {
            return '-';
        }
        return format.niceTime(date);
    }

    return Object.freeze({
        elapsedTime: elapsedTime,
        niceElapsedTime: niceElapsedTime,
        niceTime: niceTime
    });
});<commit_msg>remove log line<commit_after>/*global define*/
/*jslint white:true,browser:true*/

define([
    'kb_common/format',
], function (format) {
    'use strict';

    function pad(string, width, char, right) {
        if (!char) {
            char = '0';
        }
        if (typeof string === 'number') {
            string = String(string);
        }
        var padLen = width - string.length,
            padding = '', i;
        if (padLen <= 0) {
            return string;
        }
        for (i = 0; i < padLen; i += 1) {
            padding += char;
        }
        if (right) {
            return string + padding;
        }
        return padding + string;
    }

    function elapsedTime(value, defaultValue) {
        if (!value) {
            return defaultValue;
        }
        var temp = value,
            units = [1000, 60, 60, 24].map(function (unit) {
            var unitValue = temp % unit;
            temp = (temp - unitValue) / unit;
            return unitValue;
        });

        return [pad(units[3], 2), pad(units[2], 2), pad(units[1], 2)].join(':');
    }

    function niceElapsedTime(date) {
        if (!date) {
            return '-';
        }
        return format.niceElapsedTime(date);
    }

    function niceTime(date) {
        if (!date) {
            return '-';
        }
        return format.niceTime(date);
    }

    return Object.freeze({
        elapsedTime: elapsedTime,
        niceElapsedTime: niceElapsedTime,
        niceTime: niceTime
    });
});<|endoftext|>


<commit_before>/*!
 * Escaper
 * https://github.com/kobezzza/Escaper
 *
 * Released under the MIT license
 * https://github.com/kobezzza/Escaper/blob/master/LICENSE
 */

//#include ../../node_modules/closurecompiler-externs/buffer.js
//#include ../../node_modules/closurecompiler-externs/events.js
//#include ../../node_modules/closurecompiler-externs/stream.js
//#include ../../node_modules/closurecompiler-externs/process.js
//#include ../../node_modules/closurecompiler-externs/core.js
//#include ../../externs.js

function define(moduleName, dependencies, fn) {}
define.amd = null;
<commit_msg>Added globalThis<commit_after>/*!
 * Escaper
 * https://github.com/kobezzza/Escaper
 *
 * Released under the MIT license
 * https://github.com/kobezzza/Escaper/blob/master/LICENSE
 */

//#include ../../node_modules/closurecompiler-externs/buffer.js
//#include ../../node_modules/closurecompiler-externs/events.js
//#include ../../node_modules/closurecompiler-externs/stream.js
//#include ../../node_modules/closurecompiler-externs/process.js
//#include ../../node_modules/closurecompiler-externs/core.js
//#include ../../externs.js

var globalThis = window;

function define(moduleName, dependencies, fn) {}
define.amd = null;
<|endoftext|>


<commit_before>(function() {
    angular.module("angular-lightweight-markdown-editor", [
        "ngSanitize"
    ]).directive("markdownEditor", angularMarkdownEditor);

    var textareaElement;
    var translationTexts = {
        "textPreview": "Preview",
        "textProvideText": "Please provide link text",
        "textProvideLink": "Please provide link URL"
    };

    if (typeof showdown !== "undefined") {
        var mdConverter = new showdown.Converter();
    }

    var defaultOptions = {
        controls: [
            "bold",
            "italic",
            "strikethrough",
            "separator",
            "heading",
            "heading2",
            "heading3",
            "bullets",
            "numbers",
            "indent",
            "code",
            "separator",
            "link",
            "quote",
            "separator",
            "preview"
        ]
    };

    var options = {};

    function angularMarkdownEditor() {
        return {
            restrict: "E",
            templateUrl: "angular-lightweight-markdown-template.html",
            controller: markdownController,
            controllerAs: "markdownEditorCtrl",
            scope: true,
            bindToController: {
                ngModel: "=",
                textPreview: "@",
                textProvideText: "@",
                textProvideLink: "@",
                showPreview: "=",
                options: "="
            },
            require: ['^form', 'ngModel'],
            link: function(scope, element, attrs, ctrls) {
                textareaElement = element.find("textarea")[0];
                var form = ctrls[0];
                var copyAttrToTextarea = [
                    "name", "required", "minLength", "maxLength", "placeholder", "selectionDirection", "selectionStart", "selectionEnd", "spellcheck"
                ];
                angular.forEach(copyAttrToTextarea, function(param) {
                    if (attrs[param]) {
                        textareaElement[param] = attrs[param];
                    }
                });
            }
        }
    }

    function markdownController($sce) {
        this.preview = false;

		if(typeof this.showPreview !== "undefined") {
        	this.preview = this.showPreview;
        }

        this.showdownEnabled = (typeof showdown !== "undefined");

        for (var key in translationTexts) {
            if (angular.isDefined(this[key])) {
                translationTexts[key] = this[key];
            }
        }
        this.translations = translationTexts;

        this.action = function(name) {
            var result = actions[name](this.ngModel, getSelectionInfo());
            if (result !== false) {
                this.ngModel = result;
            }
        };

        this.getHTML = function() {
            if (!this.showdownEnabled) {
                return "";
            }
		// Removing $sce.trustAsHtml allows ngSanitize to work on the HTML and provides XSS prevention
            return mdConverter.makeHtml(this.ngModel);
        };

        this.options = angular.extend({}, defaultOptions, this.options);
        this.icons = icons;
    }

    function getSelectionInfo() {
        return {
            start: textareaElement.selectionStart,
            end: textareaElement.selectionEnd,
            length: textareaElement.selectionEnd - textareaElement.selectionStart
        };
    }

    var actions = {
        bold: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            return helpers.surround(model, selection.start, selection.end - selection.start, "**", "**");
        },
        italic: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            return helpers.surround(model, selection.start, selection.end - selection.start, "*", "*");
        },
        bullets: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "* ");
        },
        numbers: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "1. ");
        },
        heading: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "#");
        },
        heading2: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "##");
        },
        heading3: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "###");
        },
        strikethrough: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            return helpers.surround(model, selection.start, selection.end - selection.start, "--", "--");
        },
        indent: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "\t");
        },
        quote: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "> ");
        },
        code: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            var startpos = model.substr(0, selection.start).lastIndexOf("\n") + 1;
            var nextNewLine = model.substr(selection.end).indexOf("\n");
            if (nextNewLine == -1) {
                var endpos = model.length;
            } else {
                var endpos = selection.end + nextNewLine + 1;
            }
            return [
                model.substr(0, startpos),
                "```\n",
                model.substr(startpos, endpos - startpos),
                "\n```\n",
                model.substr(endpos)
            ].join("");
        },
        link: function(model, selection) {
            if (selection.length > 0) {
                var text = model.substr(selection.start, selection.length);
            } else {
                var text = prompt(translationTexts["textProvideText"]);
                if (!text) {
                    return false;
                }
            }
            var link = prompt(translationTexts["textProvideLink"]);
            if (!link) {
                return false;
            }

            return [
                model.substr(0, selection.start),
                "[" + text + "]",
                "(" + link + ")",
                model.substr(selection.end)
            ].join("");
        }
    };

    var helpers = {
        surround: function(text, start, length, before, after) {
            var between = text.substr(start, length);
            return [
                text.substr(0, start),
                (before ? before : ""),
                between,
                (after ? after : ""),
                text.substr(start + length)
            ].join("");
        },
        startLinesWith: function(text, start, end, startWith) {
            var lineStartPositions = helpers.indexes(text.substr(start, end - start), "\n", start);
            var firstpos = text.substr(0, start).lastIndexOf("\n") + 1;
            text = [text.substr(0, firstpos), startWith, text.substr(firstpos)].join("");
            for (var i = 0; i < lineStartPositions.length; i++) {
                text = [
                    text.substr(0, startWith.length * (i+1) + lineStartPositions[i] + 1),
                    startWith,
                    text.substr(startWith.length * (i+1) + lineStartPositions[i] + 1)
                ].join("");
            }
            return text;
        },
        indexes: function(source, find, add) {
            var result = [];
            for (i = 0; i < source.length; ++i) {
                if (source.substring(i, i + find.length) == find) {
                    result.push(i + add);
                }
            }
            return result;
        }
    };

    var icons = {
        "bold": "ame-bold",
        "italic": "ame-italic",
        "strikethrough": "ame-strikethrough",
        "heading": "ame-header",
        "heading2": "ame-header",
        "heading3": "ame-header",
        "bullets": "ame-list-ul",
        "numbers": "ame-list-ol",
        "indent": "ame-indent",
        "code": "ame-code",
        "link": "ame-link",
        "quote": "ame-quote-right"
    };
})();
<commit_msg>Moving textareaElement from global scope to instace'es $scope (#10)<commit_after>(function() {
    angular.module("angular-lightweight-markdown-editor", [
        "ngSanitize"
    ]).directive("markdownEditor", angularMarkdownEditor);

    var translationTexts = {
        "textPreview": "Preview",
        "textProvideText": "Please provide link text",
        "textProvideLink": "Please provide link URL"
    };

    if (typeof showdown !== "undefined") {
        var mdConverter = new showdown.Converter();
    }

    var defaultOptions = {
        controls: [
            "bold",
            "italic",
            "strikethrough",
            "separator",
            "heading",
            "heading2",
            "heading3",
            "bullets",
            "numbers",
            "indent",
            "code",
            "separator",
            "link",
            "quote",
            "separator",
            "preview"
        ]
    };

    var options = {};

    function angularMarkdownEditor() {
        return {
            restrict: "E",
            templateUrl: "angular-lightweight-markdown-template.html",
            controller: markdownController,
            controllerAs: "markdownEditorCtrl",
            scope: true,
            bindToController: {
                ngModel: "=",
                textPreview: "@",
                textProvideText: "@",
                textProvideLink: "@",
                showPreview: "=",
                options: "="
            },
            require: ['^form', 'ngModel'],
            link: function(scope, element, attrs, ctrls) {
                scope.textareaElement = element.find("textarea")[0];
                var form = ctrls[0];
                var copyAttrToTextarea = [
                    "name", "required", "minLength", "maxLength", "placeholder", "selectionDirection", "selectionStart", "selectionEnd", "spellcheck"
                ];
                angular.forEach(copyAttrToTextarea, function(param) {
                    if (attrs[param]) {
                        scope.textareaElement[param] = attrs[param];
                    }
                });
            }
        }
    }

    function markdownController($sce, $scope) {
        this.preview = false;

		if(typeof this.showPreview !== "undefined") {
        	this.preview = this.showPreview;
        }

        this.showdownEnabled = (typeof showdown !== "undefined");

        for (var key in translationTexts) {
            if (angular.isDefined(this[key])) {
                translationTexts[key] = this[key];
            }
        }
        this.translations = translationTexts;

        this.action = function(name) {
            var result = actions[name](this.ngModel, getSelectionInfo($scope.textareaElement));
            if (result !== false) {
                this.ngModel = result;
            }
        };

        this.getHTML = function() {
            if (!this.showdownEnabled) {
                return "";
            }
		// Removing $sce.trustAsHtml allows ngSanitize to work on the HTML and provides XSS prevention
            return mdConverter.makeHtml(this.ngModel);
        };

        this.options = angular.extend({}, defaultOptions, this.options);
        this.icons = icons;
    }

    function getSelectionInfo(textareaElement) {
        return {
            start: textareaElement.selectionStart,
            end: textareaElement.selectionEnd,
            length: textareaElement.selectionEnd - textareaElement.selectionStart
        };
    }

    var actions = {
        bold: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            return helpers.surround(model, selection.start, selection.end - selection.start, "**", "**");
        },
        italic: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            return helpers.surround(model, selection.start, selection.end - selection.start, "*", "*");
        },
        bullets: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "* ");
        },
        numbers: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "1. ");
        },
        heading: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "#");
        },
        heading2: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "##");
        },
        heading3: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "###");
        },
        strikethrough: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            return helpers.surround(model, selection.start, selection.end - selection.start, "--", "--");
        },
        indent: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "\t");
        },
        quote: function(model, selection) {
            return helpers.startLinesWith(model, selection.start, selection.end, "> ");
        },
        code: function(model, selection) {
            if (selection.length == 0) {
                return model;
            }

            var startpos = model.substr(0, selection.start).lastIndexOf("\n") + 1;
            var nextNewLine = model.substr(selection.end).indexOf("\n");
            if (nextNewLine == -1) {
                var endpos = model.length;
            } else {
                var endpos = selection.end + nextNewLine + 1;
            }
            return [
                model.substr(0, startpos),
                "```\n",
                model.substr(startpos, endpos - startpos),
                "\n```\n",
                model.substr(endpos)
            ].join("");
        },
        link: function(model, selection) {
            if (selection.length > 0) {
                var text = model.substr(selection.start, selection.length);
            } else {
                var text = prompt(translationTexts["textProvideText"]);
                if (!text) {
                    return false;
                }
            }
            var link = prompt(translationTexts["textProvideLink"]);
            if (!link) {
                return false;
            }

            return [
                model.substr(0, selection.start),
                "[" + text + "]",
                "(" + link + ")",
                model.substr(selection.end)
            ].join("");
        }
    };

    var helpers = {
        surround: function(text, start, length, before, after) {
            var between = text.substr(start, length);
            return [
                text.substr(0, start),
                (before ? before : ""),
                between,
                (after ? after : ""),
                text.substr(start + length)
            ].join("");
        },
        startLinesWith: function(text, start, end, startWith) {
            var lineStartPositions = helpers.indexes(text.substr(start, end - start), "\n", start);
            var firstpos = text.substr(0, start).lastIndexOf("\n") + 1;
            text = [text.substr(0, firstpos), startWith, text.substr(firstpos)].join("");
            for (var i = 0; i < lineStartPositions.length; i++) {
                text = [
                    text.substr(0, startWith.length * (i+1) + lineStartPositions[i] + 1),
                    startWith,
                    text.substr(startWith.length * (i+1) + lineStartPositions[i] + 1)
                ].join("");
            }
            return text;
        },
        indexes: function(source, find, add) {
            var result = [];
            for (i = 0; i < source.length; ++i) {
                if (source.substring(i, i + find.length) == find) {
                    result.push(i + add);
                }
            }
            return result;
        }
    };

    var icons = {
        "bold": "ame-bold",
        "italic": "ame-italic",
        "strikethrough": "ame-strikethrough",
        "heading": "ame-header",
        "heading2": "ame-header",
        "heading3": "ame-header",
        "bullets": "ame-list-ul",
        "numbers": "ame-list-ol",
        "indent": "ame-indent",
        "code": "ame-code",
        "link": "ame-link",
        "quote": "ame-quote-right"
    };
})();
<|endoftext|>


<commit_before>'use strict';

var ngConstant = require('../index');
var _ = require('lodash');
var gutil = require('gulp-util');
var through = require('through2');

// TODO: add custom matcher to test the modules name expect(output).toHaveModule('ngConstants') that uses regexp
// TODO: consider adding a toString() property to the vinyl file (e.g. file.text)

describe('ngConstant', function () {

    describe('file stream', function () {
        it('load the constants from a YAML file', function (done) {
            var contents = 'message: happy yaml';
            getStream({path: 'constants.yml', contents: new Buffer(contents)})
            .pipe(ngConstant())
            .on('data', function (file) {
                expect(file.contents.toString()).toContain('constant("message", "happy yaml")');
                done();
            });
        });

        it ('loads the constants from a JSON file', function (done) {
            var contents = '{ "message": "valid JSON" }';
            getStream({path: 'constants.json', contents: new Buffer(contents)})
            .pipe(ngConstant())
            .on('data', function (file) {
                expect(file.contents.toString()).toContain('constant("message", "valid JSON")');
                done();
            });
        });
    });

    describe('name', function () {
        it ('uses the streamed file name by default', function (done) {
            getStream({path: 'myConstantsFile.json'})
            .pipe(ngConstant())
            .on('data', function (file) {
                expect(file.contents.toString()).toContain('module("myConstantsFile"');
                done();
            });
        });

        it ('creates a modules with "ngConstants" name by default for new streams', function (done) {
            evalNgConstant({name: undefined, stream: true}, function (_, output) {
                expect(output).toContain('module("ngConstants"');
                done();
            });
        });

        it ('creates a module with the given name', function (done) {
            evalNgConstant({name: 'myConstantsModule'}, function (_, output) {
                expect(output).toContain('module("myConstantsModule"');
                done();
            });
        });
    });

    describe('deps', function () {
        it ('creates a new modules by default', function (done) {
            evalNgConstant({name: 'defaultDeps', deps: undefined}, function (_, output) {
                expect(output).toContain('module("defaultDeps", [])');
                done();
            });
        });

        it ('adds the given dependencies', function (done) {
            evalNgConstant({name: 'withDeps', deps: ['ngAnimate']}, function (_, output) {
                expect(output).toContain('module("withDeps", ["ngAnimate"])');
                done();
            });
        });

        it ('adds constants to an existing module when set to `false`', function (done) {
            evalNgConstant({name: 'noDeps', deps: false}, function (_, output) {
               expect(output).toContain('module("noDeps")');
                done();
            });
        });
    });

    describe('stream', function () {
        it ('returns an empty open stream when set to `false`', function () {
            var plugin = ngConstant({stream: false});
            expect(plugin._readableState.ended).toBe(false);
            expect(plugin._readableState.length).toBe(0);
        });

        it ('returns a closed stream with a file when set to `true`', function () {
            var stream = ngConstant({stream: true});
            expect(stream._readableState.ended).toBe(true);
            expect(stream._readableState.length).toBe(1);
        });
    });
});

describe('ngConstant.getConstants', function () {
    it('returns an array with the constants key and json string value', function () {
        var data = { constants: { hello: { foo: 'bar' } } };
        var result = ngConstant.getConstants(data);
        expect(result[0]).toEqual({name: 'hello', value: '{"foo":"bar"}'});
    });

    it('extends the data.constants with the options.constants', function () {
        var data = { constants: { hello: 'andrew' } };
        var opts = { constants: { hello: 'world' } };
        var result = ngConstant.getConstants(data, opts);
        expect(result[0]).toEqual({ name: 'hello', value: '"world"' });
    });

    it('uses the data object if data.constants is not available', function () {
        var data = { hello: 'andrew' };
        var result = ngConstant.getConstants(data);
        expect(result[0]).toEqual({ name: 'hello', value: '"andrew"' });
    });

    it('accepts a JSON string as constants from the options', function () {
        var opts = { constants: JSON.stringify({ hello: 'world' }) };
        var result = ngConstant.getConstants({}, opts);
        expect(result[0]).toEqual({ name: 'hello', value: '"world"' });
    });

    it('stringifies the value with the given option.space', function () {
        var data = { constants: { hello: { foo: 'bar' } } };
        var result = ngConstant.getConstants(data, { space: '' });
        expect(result[0].value).toEqual('{"foo":"bar"}');
        result = ngConstant.getConstants(data, { space: ' ' });
        expect(result[0].value).toEqual('{\n "foo": "bar"\n}');
    });
});

describe('ngConstant.getFilePath', function() {
    it('returns the file path from the src plugin when option dest is undefined', function() {
        expect(ngConstant.getFilePath('/foo/bar/config.json', {})).toBe('/foo/bar/config.js');
    });

    it('returns the file path defined by the dest option', function() {
        expect(ngConstant.getFilePath('/foo/bar/foo.js', { dest: 'foo.js' })).toBe('/foo/bar/foo.js');
    });
});

function getStream(fileOptions) {
    var defaults = {path: 'constants.json'};
    var file = new gutil.File(_.merge(defaults, fileOptions));
    var stream = through.obj(gutil.noop());
    stream.end(file);
    return stream;
}

function evalNgConstant(options, callback) {
    var defaults = {stream: true, constants: {greeting: 'hello' }};
    ngConstant(_.merge(defaults, options)).on('data', function (file) {
        callback(file, file.contents.toString());
    });
}
<commit_msg>chore(test): add test for extending file constants with config constants<commit_after>'use strict';

var ngConstant = require('../index');
var _ = require('lodash');
var gutil = require('gulp-util');
var through = require('through2');

// TODO: add custom matcher to test the modules name expect(output).toHaveModule('ngConstants') that uses regexp
// TODO: consider adding a toString() property to the vinyl file (e.g. file.text)

describe('ngConstant', function () {

    describe('file stream', function () {
        it('load the constants from a YAML file', function (done) {
            var contents = 'message: happy yaml';
            getStream({path: 'constants.yml', contents: new Buffer(contents)})
            .pipe(ngConstant())
            .on('data', function (file) {
                expect(file.contents.toString()).toContain('constant("message", "happy yaml")');
                done();
            });
        });

        it ('loads the constants from a JSON file', function (done) {
            var contents = '{ "message": "valid JSON" }';
            getStream({path: 'constants.json', contents: new Buffer(contents)})
            .pipe(ngConstant())
            .on('data', function (file) {
                expect(file.contents.toString()).toContain('constant("message", "valid JSON")');
                done();
            });
        });

        it ('extends the constants from a JSON file with the ones defined in the config', function (done) {
            var contents = '{ "lastName": "Gomez", "message": "message from JSON" }';
            getStream({path: 'constants.json', contents: new Buffer(contents)})
            .pipe(ngConstant({constants: {message: "message from config", greet: "hello"}}))
            .on('data', function (file) {
                var output = file.contents.toString();
                expect(output).toContain('constant("lastName", "Gomez")');
                expect(output).not.toContain('message from JSON');
                expect(output).toContain('constant("greet", "hello")');
                done();
            });
        });
    });

    describe('name', function () {
        it ('uses the streamed file name by default', function (done) {
            getStream({path: 'myConstantsFile.json'})
            .pipe(ngConstant())
            .on('data', function (file) {
                expect(file.contents.toString()).toContain('module("myConstantsFile"');
                done();
            });
        });

        it ('creates a modules with "ngConstants" name by default for new streams', function (done) {
            evalNgConstant({name: undefined, stream: true}, function (_, output) {
                expect(output).toContain('module("ngConstants"');
                done();
            });
        });

        it ('creates a module with the given name', function (done) {
            evalNgConstant({name: 'myConstantsModule'}, function (_, output) {
                expect(output).toContain('module("myConstantsModule"');
                done();
            });
        });
    });

    describe('deps', function () {
        it ('creates a new modules by default', function (done) {
            evalNgConstant({name: 'defaultDeps', deps: undefined}, function (_, output) {
                expect(output).toContain('module("defaultDeps", [])');
                done();
            });
        });

        it ('adds the given dependencies', function (done) {
            evalNgConstant({name: 'withDeps', deps: ['ngAnimate']}, function (_, output) {
                expect(output).toContain('module("withDeps", ["ngAnimate"])');
                done();
            });
        });

        it ('adds constants to an existing module when set to `false`', function (done) {
            evalNgConstant({name: 'noDeps', deps: false}, function (_, output) {
               expect(output).toContain('module("noDeps")');
                done();
            });
        });
    });

    describe('stream', function () {
        it ('returns an empty open stream when set to `false`', function () {
            var plugin = ngConstant({stream: false});
            expect(plugin._readableState.ended).toBe(false);
            expect(plugin._readableState.length).toBe(0);
        });

        it ('returns a closed stream with a file when set to `true`', function () {
            var stream = ngConstant({stream: true});
            expect(stream._readableState.ended).toBe(true);
            expect(stream._readableState.length).toBe(1);
        });
    });
});

describe('ngConstant.getConstants', function () {
    it('returns an array with the constants key and json string value', function () {
        var data = { constants: { hello: { foo: 'bar' } } };
        var result = ngConstant.getConstants(data);
        expect(result[0]).toEqual({name: 'hello', value: '{"foo":"bar"}'});
    });

    it('extends the data.constants with the options.constants', function () {
        var data = { constants: { hello: 'andrew' } };
        var opts = { constants: { hello: 'world' } };
        var result = ngConstant.getConstants(data, opts);
        expect(result[0]).toEqual({ name: 'hello', value: '"world"' });
    });

    it('uses the data object if data.constants is not available', function () {
        var data = { hello: 'andrew' };
        var result = ngConstant.getConstants(data);
        expect(result[0]).toEqual({ name: 'hello', value: '"andrew"' });
    });

    it('accepts a JSON string as constants from the options', function () {
        var opts = { constants: JSON.stringify({ hello: 'world' }) };
        var result = ngConstant.getConstants({}, opts);
        expect(result[0]).toEqual({ name: 'hello', value: '"world"' });
    });

    it('stringifies the value with the given option.space', function () {
        var data = { constants: { hello: { foo: 'bar' } } };
        var result = ngConstant.getConstants(data, { space: '' });
        expect(result[0].value).toEqual('{"foo":"bar"}');
        result = ngConstant.getConstants(data, { space: ' ' });
        expect(result[0].value).toEqual('{\n "foo": "bar"\n}');
    });
});

describe('ngConstant.getFilePath', function() {
    it('returns the file path from the src plugin when option dest is undefined', function() {
        expect(ngConstant.getFilePath('/foo/bar/config.json', {})).toBe('/foo/bar/config.js');
    });

    it('returns the file path defined by the dest option', function() {
        expect(ngConstant.getFilePath('/foo/bar/foo.js', { dest: 'foo.js' })).toBe('/foo/bar/foo.js');
    });
});

function getStream(fileOptions) {
    var defaults = {path: 'constants.json'};
    var file = new gutil.File(_.merge(defaults, fileOptions));
    var stream = through.obj(gutil.noop());
    stream.end(file);
    return stream;
}

function evalNgConstant(options, callback) {
    var defaults = {stream: true, constants: {greeting: 'hello' }};
    ngConstant(_.merge(defaults, options)).on('data', function (file) {
        callback(file, file.contents.toString());
    });
}
<|endoftext|>


<commit_before>window.cedac = window.cedac || {};

(function(){

    // initialize map
    function initMap( center, zoom ) {
        var map = L.map( "map", {
                minZoom: 8,
                maxZoom: 16
            } )
            .setView( center, zoom );

        // 2 hardcoded basemaps...
        var basemaps = [
            {
                title: "MAPC Basemap",
                category: "baselayerlist",
                layer: new L.MAPCTileLayer( "basemap" ),
                visible: true,
                zindex: 10
            },
            {
                title: "Bing Aerial",
                category: "baselayerlist",
                layer: new L.BingLayer("An8pfp-PjegjSInpD2JyXw5gMufAZBvZ_q3cbJb-kWiZ1H55gpJbxndbFHPsO_HN", "Aerial"),
                visible: false,
                zindex: 20,
            }
        ];
        this.initLayers( basemaps, map );

        var hash = new L.Hash(map);

        return map;
    }

    // initialize category menu
    function initCategories ( categories ) {
        // category menue
        // TODO: move to html template
        var html = _.template( "
 \

 \
                <a class='accordion-toggle collapsed' data-toggle='collapse' href='#<%= slug %>'> \
                    <%= title %> \
                 \

 \
            <div id='<%= slug %>' class='accordion-body collapse'> \

 \

 \

" );

        _( categories ).forEach( function( category ) {
            $("#overlaylist").append( html( category ) );
        });
    }

    // initialize layers
    function initLayers( layers, map) {
        _( layers ).forEach( function( layer ) {

            // Leaflet Layer Object or new WMS layer
            if ( _.has(layer, 'layer') ) {
                var llLayer = layer.layer;
            }
            if ( _.has(layer, 'wms') ) {
                var llLayer = L.tileLayer.wms( layer.wms.url , {
                    layers: layer.wms.layers,
                    styles: layer.wms.styles,
                    format: layer.wms.format,
                    transparent: layer.wms.transparent,
                    attribution: layer.wms.attribution
                });
                llLayer.setOpacity(0.8);
                var legend = layer.wms.url + "?VERSION=1.1.0&REQUEST=GetLegendGraphic&FORMAT=image/png&legend_options=fontAntiAliasing&LAYER=" + layer.wms.layers;
            }
            var legend = legend || "";

            // instantiate new Layer
            var options = _.assign( layer , { 'layer': llLayer, 'legend': legend, 'map': map });
            var maplayer = new cedac.Layer( options );

            // keep track of baselayers
            if ( layer.category === "baselayerlist" ) {
                cedac.baselayerlist.push( maplayer );
            }
            if (layer.visible) maplayer.show();
        });
    }

    // resize map (and sidebar accordingly) between 8 and 12 columns
    var mapwidths = [ 'span8', 'span12' ];
    function resize( map, mapcontainer, sidebar, oldheight ) {
        $( mapcontainer ).removeClass( mapwidths[0] ); // oldwith
        $( mapcontainer ).addClass( mapwidths[1] ); // newwidth

        if ( mapwidths[1] === 'span12' ) { // larger map
            var display = 'none',
                mapheight = $(window).height() - 250,
                btn = {
                    btntext : 'Smaller Map',
                    btnicon : 'icon-resize-small'
                };
                mapheight = mapheight < 500 ? '500px' : mapheight + 'px';
            // TODO: redraw basemap
        } else {
            var display = 'block',
                mapheight = '500px',
                btn = {
                    btntext : 'Larger Map',
                    btnicon : 'icon-resize-full'
                };
        }

        mapwidths.reverse();

        var btn_html = _.template( '<i class="<%= btnicon %>"> <%= btntext %>' );
        $("#resize-btn").html( btn_html( btn ) )
        // FIXME: map shouldn't be hardcoded
        $( "#map" ).css( 'height', mapheight );
        $( sidebar ).css( 'display', display );

        map.invalidateSize( true );
    }

    // expose functions
    cedac.initMap = initMap;
    cedac.initLayers = initLayers;
    cedac.initCategories = initCategories;
    cedac.resize = resize;

    // baselayers are radios, only one visible at a time
    cedac.baselayerlist = [];

    // Layer module
    // TODO: maybe extend L.Class (http://leafletjs.com/reference.html#ilayer) instead?
    cedac.Layer = (function() {

        // initial
        var Layer = function( options ) {
            this.layer = options.layer;
            this.title = options.title;
            this.category = options.category;
            this.category_slug = options.category.toLowerCase().replace(" ", "_");
            this.map = options.map;
            this.uuid = _.uniqueId( this.category_slug + "_" );
            this.legend = options.legend;
            this.zindex = options.zindex

            // add layer to appropriate category
            if (this.category === "baselayerlist") {
                var html = _.template( "
<input type='radio' name='baselayer' id='<%= uuid %>'> <%= title %>
" );
            } else {
                var html = _.template( "
<input type='checkbox' id='<%= uuid %>'> <%= title %>
" );
            }
            var $el = $(html(this));
            $( $el ).on("change", this, function( event ) {
                event.data.toogle();
            });
            $( "#" + this.category_slug + " ul" ).append( $el );
        };

        Layer.prototype.show = function() {
            if (this.category === "baselayerlist") {
                _( cedac.baselayerlist ).forEach( function( baselayer ) {
                   baselayer.hide();
                });
                this.map.addLayer( this.layer);
            } else {
                // add layer legend image in sidebar
                this.map.addLayer( this.layer);
                var html = _.template( "<img class='legend_<%= uuid %>' src='<%= legend %>' alt='<%= title %> - Legend'>" );
                $("#" + this.uuid).parent().after( html(this) );
                // and to print legend
                var print_html = _.template( "
<%= title %>
<img class='legend_<%= uuid %>' src='<%= legend %>' alt='<%= title %> - Legend'>
" );
                $(".print-legend ul").append( print_html(this) );
            }
            this.layer.setZIndex( this.zindex );
            $("#" + this.uuid).prop("checked", true);
        }

        Layer.prototype.hide = function() {
            if ( this.map.hasLayer( this.layer ) ) this.map.removeLayer( this.layer );
            $("#" + this.uuid).prop("checked", false);
            $(".sidebar .legend_" + this.uuid).remove();
            $(".print-legend .legend_" + this.uuid).parent().remove();
        }

        Layer.prototype.toogle = function() {
            if ( $("#" + this.uuid).prop("checked") ) {
                this.show();
            } else {
                this.hide();
            }
        }

        return Layer;

    }());

})();

$( document ).ready(function() {

    var map = cedac.initMap( [42.35, -71.6], 9 );

    // map tools
    $( '#resize-btn' ).on( 'click', function() {
        var oldheight = $( '#map' ).height();
        cedac.resize( map, '.mapcontainer', '.sidebar', oldheight );
    });
    $( '#email-btn' ).on( 'click', function() {
        $( this ).attr( 'href', 'mailto:?subject=CEDAC Expiring Use Properties&body=' + document.URL );
    });
    $( '#print-btn' ).on( 'click', function() {
        $( '.print-legend p:first-child' ).text( document.URL );
        window.print();
    });

    // add categories and overlays
    $.getJSON('/appconfig', function(data) {

        // build category menu
        // FIXME: deferred callback for layers when categories are rendered?
        cedac.initCategories( data.categories );

        // add map overlay layers
        cedac.initLayers( data.layers, map );
    });

    // load CEDAC properties into property layer
    // TODO: cleanup to own or layer module
    $.getJSON('/properties', function(data) {

        var icon = new L.Icon({
            iconUrl: '/static/properties/img/home.png',
            shadowUrl: null,
            iconSize: new L.Point(32, 37),
            shadowSize: null,
            iconAnchor: new L.Point(16, 37),
            popupAnchor: new L.Point(2, -32)
        });

        var popup_html = _.template(
            $( 'script.map-popup' ).html()
        );

        var geoJSONLayer = L.geoJson( data, {
            pointToLayer: function( feature, latlng ) {
                return new L.Marker( latlng, {
                    icon: icon
                })
            },
            onEachFeature: function (feature, layer) {
                layer.bindPopup( popup_html( feature.properties ) );
            }
        });

        var markers = new L.MarkerClusterGroup({
            disableClusteringAtZoom: 12,
            iconCreateFunction: function (cluster) {
                return new L.DivIcon({ html: '
' + cluster.getChildCount() + '
', className: 'cedac-cluster', iconSize: new L.Point(40, 40) });
            },
            showCoverageOnHover: false,
            polygonOptions: {
                color: '#008C99',
                weight: 2
            },
            maxClusterRadius: 110
        }).addLayer( geoJSONLayer );

        map.addLayer(markers);

    });

});<commit_msg>some js cleanup<commit_after>window.cedac = window.cedac || {};

(function(){

    // initialize map
    function initMap( center, zoom ) {
        var map = L.map( "map", {
                minZoom: 8,
                maxZoom: 16
            } )
            .setView( center, zoom );

        // 2 hardcoded basemaps...
        var basemaps = [
            {
                title: "MAPC Basemap",
                category: "baselayerlist",
                layer: new L.MAPCTileLayer( "basemap" ),
                visible: true,
                zindex: 10
            },
            {
                title: "Bing Aerial",
                category: "baselayerlist",
                layer: new L.BingLayer("An8pfp-PjegjSInpD2JyXw5gMufAZBvZ_q3cbJb-kWiZ1H55gpJbxndbFHPsO_HN", "Aerial"),
                visible: false,
                zindex: 20,
            }
        ];
        this.initLayers( basemaps, map );

        var hash = new L.Hash(map);

        return map;
    }

    // initialize category menu
    function initCategories ( categories ) {
        // category menue
        // TODO: move to html template
        var html = _.template( "
 \

 \
                <a class='accordion-toggle collapsed' data-toggle='collapse' href='#<%= slug %>'> \
                    <%= title %> \
                 \

 \
            <div id='<%= slug %>' class='accordion-body collapse'> \

 \

 \

" );

        _( categories ).forEach( function( category ) {
            $("#overlaylist").append( html( category ) );
        });
    }

    // initialize layers
    function initLayers( layers, map) {
        _( layers ).forEach( function( layer ) {

            // Leaflet Layer Object or new WMS layer
            if ( _.has(layer, 'layer') ) {
                var llLayer = layer.layer;
            } else if ( _.has(layer, 'wms') ) {
                var llLayer = L.tileLayer.wms( layer.wms.url , {
                    layers: layer.wms.layers,
                    styles: layer.wms.styles,
                    format: layer.wms.format,
                    transparent: layer.wms.transparent,
                    attribution: layer.wms.attribution
                });
                llLayer.setOpacity(0.8);
                var legend = layer.wms.url + "?VERSION=1.1.0&REQUEST=GetLegendGraphic&FORMAT=image/png&legend_options=fontAntiAliasing&LAYER=" + layer.wms.layers;
            }
            var legend = legend || "";

            // instantiate new Layer
            var options = _.assign( layer , { 'layer': llLayer, 'legend': legend, 'map': map });
            var maplayer = new cedac.Layer( options );

            // keep track of baselayers
            if ( layer.category === "baselayerlist" ) {
                cedac.baselayerlist.push( maplayer );
            }
            if (layer.visible) maplayer.show();
        });
    }

    // resize map (and sidebar accordingly) between 8 and 12 columns
    var mapwidths = [ 'span8', 'span12' ];
    function resize( map, mapcontainer, sidebar, oldheight ) {
        $( mapcontainer ).removeClass( mapwidths[0] ); // oldwith
        $( mapcontainer ).addClass( mapwidths[1] ); // newwidth

        if ( mapwidths[1] === 'span12' ) { // larger map
            var display = 'none',
                mapheight = $(window).height() - 250,
                btn = {
                    btntext : 'Smaller Map',
                    btnicon : 'icon-resize-small'
                };
                mapheight = mapheight < 500 ? '500px' : mapheight + 'px';
            // TODO: redraw basemap
        } else {
            var display = 'block',
                mapheight = '500px',
                btn = {
                    btntext : 'Larger Map',
                    btnicon : 'icon-resize-full'
                };
        }

        mapwidths.reverse();

        var btn_html = _.template( '<i class="<%= btnicon %>"> <%= btntext %>' );
        $("#resize-btn").html( btn_html( btn ) )
        // FIXME: map shouldn't be hardcoded
        $( "#map" ).css( 'height', mapheight );
        $( sidebar ).css( 'display', display );

        map.invalidateSize( true );
    }

    // expose functions
    cedac.initMap = initMap;
    cedac.initLayers = initLayers;
    cedac.initCategories = initCategories;
    cedac.resize = resize;

    // baselayers are radios, only one visible at a time
    cedac.baselayerlist = [];

    // Layer module
    // TODO: maybe extend L.Class (http://leafletjs.com/reference.html#ilayer) instead?
    cedac.Layer = (function() {

        // initial
        var Layer = function( options ) {
            this.layer = options.layer;
            this.title = options.title;
            this.category = options.category;
            this.category_slug = options.category.toLowerCase().replace(" ", "_");
            this.map = options.map;
            this.uuid = _.uniqueId( this.category_slug + "_" );
            this.legend = options.legend;
            this.zindex = options.zindex

            // add layer to appropriate category
            if (this.category === "baselayerlist") {
                var html = _.template( "
<input type='radio' name='baselayer' id='<%= uuid %>'> <%= title %>
" );
            } else {
                var html = _.template( "
<input type='checkbox' id='<%= uuid %>'> <%= title %>
" );
            }
            var $el = $(html(this));
            $( $el ).on("change", this, function( event ) {
                event.data.toogle();
            });
            $( "#" + this.category_slug + " ul" ).append( $el );
        };

        Layer.prototype.show = function() {
            if (this.category === "baselayerlist") {
                _( cedac.baselayerlist ).forEach( function( baselayer ) {
                   baselayer.hide();
                });
                this.map.addLayer( this.layer );
            } else {
                // add layer legend image in sidebar
                this.map.addLayer( this.layer);
                var html = _.template( "<img class='legend_<%= uuid %>' src='<%= legend %>' alt='<%= title %> - Legend'>" );
                $( "#" + this.uuid ).parent().after( html( this ) );
                // and to print legend
                var print_html = _.template( "
<%= title %>
<img class='legend_<%= uuid %>' src='<%= legend %>' alt='<%= title %> - Legend'>
" );
                $( ".print-legend ul" ).append( print_html( this ) );
            }
            this.layer.setZIndex( this.zindex );
            $( "#" + this.uuid ).prop( "checked", true );
        }

        Layer.prototype.hide = function() {
            if ( this.map.hasLayer( this.layer ) ) this.map.removeLayer( this.layer );
            $( "#" + this.uuid ).prop( "checked", false );
            $( ".sidebar .legend_" + this.uuid ).remove();
            $( ".print-legend .legend_" + this.uuid ).parent().remove();
        }

        Layer.prototype.toogle = function() {
            if ( $("#" + this.uuid).prop( "checked" ) ) {
                this.show();
            } else {
                this.hide();
            }
        }

        return Layer;

    }());

})();

$( document ).ready(function() {

    var map = cedac.initMap( [42.35, -71.6], 9 );

    // map tools
    $( '#resize-btn' ).on( 'click', function() {
        var oldheight = $( '#map' ).height();
        cedac.resize( map, '.mapcontainer', '.sidebar', oldheight );
    });
    $( '#email-btn' ).on( 'click', function() {
        $( this ).attr( 'href', 'mailto:?subject=CEDAC Expiring Use Properties&body=' + document.URL );
    });
    $( '#print-btn' ).on( 'click', function() {
        $( '.print-legend p:first-child' ).text( document.URL );
        window.print();
    });

    // add categories and overlays
    $.getJSON('/appconfig', function( data ) {

        // build category menu
        // FIXME: deferred callback for layers when categories are rendered?
        cedac.initCategories( data.categories );

        // add map overlay layers
        cedac.initLayers( data.layers, map );
    });

    // load CEDAC properties into property layer
    // TODO: cleanup to own or layer module
    $.getJSON('/properties', function( data ) {

        var icon = new L.Icon({
            iconUrl: '/static/properties/img/home.png',
            shadowUrl: null,
            iconSize: new L.Point(32, 37),
            shadowSize: null,
            iconAnchor: new L.Point(16, 37),
            popupAnchor: new L.Point(2, -32)
        });

        var popup_html = _.template(
            $( 'script.map-popup' ).html()
        );

        var geoJSONLayer = L.geoJson( data, {
            pointToLayer: function( feature, latlng ) {
                return new L.Marker( latlng, {
                    icon: icon
                })
            },
            onEachFeature: function ( feature, layer ) {
                layer.bindPopup( popup_html( feature.properties ) );
            }
        });

        var markers = new L.MarkerClusterGroup({
            disableClusteringAtZoom: 12,
            iconCreateFunction: function ( cluster ) {
                return new L.DivIcon({ html: '
' + cluster.getChildCount() + '
', className: 'cedac-cluster', iconSize: new L.Point(40, 40) });
            },
            showCoverageOnHover: false,
            polygonOptions: {
                color: '#008C99',
                weight: 2
            },
            maxClusterRadius: 110
        }).addLayer( geoJSONLayer );

        map.addLayer( markers );

    });

});<|endoftext|>


<commit_before>//
// RUNTIME TYPE CHECKING
//

export {
  isArray,
  isArguments,
  isEventEmitter,
  isFunction,
  isPojo,
  isString,
  isTemplateLiteral,
  isNumber,
  isThisValue,
  isUnset,
  ArgTypeError,
  ObjTypeError
}

//
// isType
//

function isEventEmitter(obj) {
  return (
    isObject(obj) &&
    isFunction(obj.emit) &&
    (isFunction(obj.addListener) || isFunction(obj.on)) &&
    (isFunction(obj.removeListener) || isFunction(obj.off))
  )
}
isEventEmitter.displayName = 'isEventEmitter'

function isUnset(obj) {
  return obj === null || obj === undefined
}
isArray.displayName = 'isUnset'

function isArray(obj) {
  return Array.isArray(obj)
}
isArray.displayName = 'isArray'

function isArguments(obj) {
  const isObject = typeof obj === 'object'
  if (!isObject || obj === null) {
    return false
  }
  const hasMap = typeof obj.map === 'function'
  const hasLength = typeof obj.length === 'number'
  const hasObjectPrototype = obj.__proto__ === Object.prototype
  return hasObjectPrototype && isObject && hasLength && !hasMap
}
isArguments.displayName = 'isArguments'

function isFunction(obj) {
  return typeof obj === 'function'
}
isFunction.displayName = 'isFunction'

function isString(obj) {
  return typeof obj === 'string'
}
isString.displayName = 'isString'

function isNumber(obj) {
  return typeof obj === 'number'
}
isNumber.displayName = 'isNumber'

function isObject(obj) {
  return typeof obj === 'object'
}
isObject.displayName = 'isObject'

function isPojo(obj) {
  if (obj === null || !isObject(obj)) {
    return false
  }
  return Object.getPrototypeOf(obj) === Object.prototype
}
isPojo.displayName = 'isPojo'

function isTemplateLiteral(obj) {
  if (isString(obj)) {
    return true
  }
  if (!isArray(obj)) {
    return false
  }
  return obj.every(isString)
}
isTemplateLiteral.displayName = 'isTemplateLiteral'

function isThisValue(value) {
  function inObject(obj) {
    return obj === value
  }
  inObject.displayName = `isThisValue(${value})`
  return inObject
}

//
// ArgTypeError
//

const typeErrorStringIfFnReturnsFalse = (argName, argTypeFn, arg) => {
  return argTypeFn(arg)
    ? undefined
    : (argTypeFn.displayName || argTypeFn.name) +
        `(${argName}) did not return true`
}

const typeErrorStringIfTypeOfFails = (argName, argType, arg) => {
  return typeof arg === argType
    ? undefined
    : `Argument "${argName}" should be a ${argType}`
}

const typeErrorStringFromArgument = (argMap, arg, index) => {
  const { argName, argType } = argMap[index]
  if (arg === undefined) {
    return `Argument undefined: "${argName}"`
  }

  const permittedArgTypes = Array.isArray(argType) ? argType : [argType]

  const errorDescs = permittedArgTypes
    .map(argType =>
      isFunction(argType)
        ? typeErrorStringIfFnReturnsFalse(argName, argType, arg)
        : typeErrorStringIfTypeOfFails(argName, argType, arg)
    )
    .filter(isString)

  const multipleTypesSpecified = permittedArgTypes.length > 1
  const shouldError = multipleTypesSpecified
    ? errorDescs.length > 1
    : errorDescs.length

  if (shouldError) {
    return (
      errorDescs.join('\n| ') +
      `\n> typeof ${argName} === ${typeof arg}(${JSON.stringify(arg)})`
    )
  }
}

/**
 * Helper for enforcing correct argument-types.
 *
 * @private
 * @param {string} errPrefix
 *
 * @example
 * const argTypeError = ArgTypeError('namespace#')
 *
 * function myFn (myArg1, myArg2) {
 *   const err = argTypeError('myFn',
 *     { myArg1: isString, myArg2: Boolean },
 *     myArg1, myArg2
 *   )
 *   if (err) {
 *     throw new TypeError(err)
 *   }
 * }
 */

function ArgTypeError(errPrefix) {
  return (fnName, typeMap, ...args) => {
    const argMap = Object.entries(typeMap).map(([argName, argType]) => ({
      argName,
      argType
    }))

    const err = args
      .map((...args) => typeErrorStringFromArgument(argMap, ...args))
      .filter(isString)

    if (!err.length) {
      return
    }

    const signature = Object.keys(typeMap).join(', ')
    return (
      `\n${errPrefix || ''}${fnName}(${signature}):\n` +
      `${err.map(err => `| ${err}`).join('\n')}`
    )
  }
}

function ObjTypeError(errPrefix) {
  const objTypeError = ArgTypeError(errPrefix)
  return (fnName, typeMap, obj) => {
    const keys = Object.keys(typeMap)
    const values = valuesOf(obj, { keys })
    const err = objTypeError(fnName, typeMap, ...values)
    return err
  }
}

function valuesOf(obj, options) {
  const { keys } = options
  if (!Array.isArray(keys)) {
    return Object.values(obj)
  }
  return keys.reduce((acc, key) => {
    return [...acc, obj[key]]
  }, [])
}
<commit_msg>Spacing<commit_after>//
// RUNTIME TYPE CHECKING
//

export {
  isArray,
  isArguments,
  isEventEmitter,
  isFunction,
  isPojo,
  isString,
  isTemplateLiteral,
  isNumber,
  isThisValue,
  isUnset,
  ArgTypeError,
  ObjTypeError
}

//
// isType
//

function isEventEmitter(obj) {
  return (
    isObject(obj) &&
    isFunction(obj.emit) &&
    (isFunction(obj.addListener) || isFunction(obj.on)) &&
    (isFunction(obj.removeListener) || isFunction(obj.off))
  )
}

isEventEmitter.displayName = 'isEventEmitter'

function isUnset(obj) {
  return obj === null || obj === undefined
}

isArray.displayName = 'isUnset'

function isArray(obj) {
  return Array.isArray(obj)
}

isArray.displayName = 'isArray'

function isArguments(obj) {
  const isObject = typeof obj === 'object'
  if (!isObject || obj === null) {
    return false
  }
  const hasMap = typeof obj.map === 'function'
  const hasLength = typeof obj.length === 'number'
  const hasObjectPrototype = obj.__proto__ === Object.prototype
  return hasObjectPrototype && isObject && hasLength && !hasMap
}

isArguments.displayName = 'isArguments'

function isFunction(obj) {
  return typeof obj === 'function'
}

isFunction.displayName = 'isFunction'

function isString(obj) {
  return typeof obj === 'string'
}

isString.displayName = 'isString'

function isNumber(obj) {
  return typeof obj === 'number'
}

isNumber.displayName = 'isNumber'

function isObject(obj) {
  return typeof obj === 'object'
}

isObject.displayName = 'isObject'

function isPojo(obj) {
  if (obj === null || !isObject(obj)) {
    return false
  }
  return Object.getPrototypeOf(obj) === Object.prototype
}

isPojo.displayName = 'isPojo'

function isTemplateLiteral(obj) {
  if (isString(obj)) {
    return true
  }
  if (!isArray(obj)) {
    return false
  }
  return obj.every(isString)
}

isTemplateLiteral.displayName = 'isTemplateLiteral'

function isThisValue(value) {
  function inObject(obj) {
    return obj === value
  }
  inObject.displayName = `isThisValue(${value})`
  return inObject
}

//
// ArgTypeError
//

const typeErrorStringIfFnReturnsFalse = (argName, argTypeFn, arg) => {
  return argTypeFn(arg)
    ? undefined
    : (argTypeFn.displayName || argTypeFn.name) +
        `(${argName}) did not return true`
}

const typeErrorStringIfTypeOfFails = (argName, argType, arg) => {
  return typeof arg === argType
    ? undefined
    : `Argument "${argName}" should be a ${argType}`
}

const typeErrorStringFromArgument = (argMap, arg, index) => {
  const { argName, argType } = argMap[index]
  if (arg === undefined) {
    return `Argument undefined: "${argName}"`
  }

  const permittedArgTypes = Array.isArray(argType) ? argType : [argType]

  const errorDescs = permittedArgTypes
    .map(argType =>
      isFunction(argType)
        ? typeErrorStringIfFnReturnsFalse(argName, argType, arg)
        : typeErrorStringIfTypeOfFails(argName, argType, arg)
    )
    .filter(isString)

  const multipleTypesSpecified = permittedArgTypes.length > 1
  const shouldError = multipleTypesSpecified
    ? errorDescs.length > 1
    : errorDescs.length

  if (shouldError) {
    return (
      errorDescs.join('\n| ') +
      `\n> typeof ${argName} === ${typeof arg}(${JSON.stringify(arg)})`
    )
  }
}

/**
 * Helper for enforcing correct argument-types.
 *
 * @private
 * @param {string} errPrefix
 *
 * @example
 * const argTypeError = ArgTypeError('namespace#')
 *
 * function myFn (myArg1, myArg2) {
 *   const err = argTypeError('myFn',
 *     { myArg1: isString, myArg2: Boolean },
 *     myArg1, myArg2
 *   )
 *   if (err) {
 *     throw new TypeError(err)
 *   }
 * }
 */

function ArgTypeError(errPrefix) {
  return (fnName, typeMap, ...args) => {
    const argMap = Object.entries(typeMap).map(([argName, argType]) => ({
      argName,
      argType
    }))

    const err = args
      .map((...args) => typeErrorStringFromArgument(argMap, ...args))
      .filter(isString)

    if (!err.length) {
      return
    }

    const signature = Object.keys(typeMap).join(', ')
    return (
      `\n${errPrefix || ''}${fnName}(${signature}):\n` +
      `${err.map(err => `| ${err}`).join('\n')}`
    )
  }
}

function ObjTypeError(errPrefix) {
  const objTypeError = ArgTypeError(errPrefix)
  return (fnName, typeMap, obj) => {
    const keys = Object.keys(typeMap)
    const values = valuesOf(obj, { keys })
    const err = objTypeError(fnName, typeMap, ...values)
    return err
  }
}

function valuesOf(obj, options) {
  const { keys } = options
  if (!Array.isArray(keys)) {
    return Object.values(obj)
  }
  return keys.reduce((acc, key) => {
    return [...acc, obj[key]]
  }, [])
}
<|endoftext|>


<commit_before>var compose = (function () {

var exports = {};
var is_composing_message = false;

exports.start = function (msg_type, opts) {
    opts = $.extend({ 'message_type': msg_type,
                      'stream': '',
                      'subject': '',
                      'huddle_recipient': '',
                      'message': '' },
                    opts);

    $("#stream").val(opts.stream);
    $("#subject").val(opts.subject);
    $("#huddle_recipient").val(opts.huddle_recipient);
    $("#new_message_content").val(opts.message);

    $('#sidebar a[href="#home"]').tab('show');

    if (msg_type !== 'stream') {
        // TODO: Just to make sure that compose.composing() output is
        // consistent.  We really should just standardize our
        // terminology
        msg_type = "huddle";
    }

    var focus_area;
    if (opts.stream && ! opts.subject) {
        focus_area = 'subject';
    } else if (opts.stream || opts.huddle_recipient) {
        focus_area = 'new_message_content';
    }

    if (msg_type === 'stream') {
        exports.show('stream', $("#" + (focus_area || 'stream')));
    } else {
        exports.show('personal', $("#" + (focus_area || 'huddle_recipient')));
    }

    hotkeys.set_compose();
    is_composing_message = msg_type;
    $(document).trigger($.Event('compose_started.zephyr', opts));
};

exports.cancel = function () {
    compose.hide();
    is_composing_message = false;
    $(document).trigger($.Event('compose_canceled.zephyr'));
};

var send_options;

$(function () {
    var send_status = $('#send-status');
    var buttons = $('#compose').find('input[type="submit"]');

    send_options = {
        dataType: 'json', // This seems to be ignored. We still get back an xhr.
        success: function (resp, statusText, xhr, form) {
            form.find('textarea').val('');
            send_status.hide();
            compose.hide();
            buttons.removeAttr('disabled');
        },
        error: function (xhr, error_type) {
            if (error_type !== 'timeout' && get_updates_params.reload_pending) {
                // The error might be due to the server changing
                reload.initiate({immediate: true, send_after_reload: true});
                return;
            }
            var response = "Error sending message";
            if (xhr.status.toString().charAt(0) === "4") {
                // Only display the error response for 4XX, where we've crafted
                // a nice response.
                response += ": " + $.parseJSON(xhr.responseText).msg;
            }
            send_status.removeClass(status_classes)
                       .addClass('alert-error')
                       .text(response)
                       .append($('<span />')
                           .addClass('send-status-close').html('×')
                           .click(function () { send_status.stop(true).fadeOut(500); }))
                       .stop(true).fadeTo(0,1);

            buttons.removeAttr('disabled');
        }
    };

    send_status.hide();
});

exports.finish = function () {
    if (! compose.validate()) {
        return false;
    }
    $("#compose form").ajaxSubmit(send_options);
    is_composing_message = false;
    $(document).trigger($.Event('compose_finished.zephyr'));
    return true;
};

$(function () {
    $("#compose form").on("submit", function (e) {
       e.preventDefault();
       compose.finish();
    });
});

exports.show = function (tabname, focus_area) {
    if (reload.is_in_progress()) {
        return;
    }
    $("#send-status").removeClass(status_classes).hide();
    $('#compose').css({visibility: "visible"});
    $("#new_message_content").trigger("autosize");
    $('.message_comp').slideDown(100);
    $('#message-type-tabs a[href="#' + tabname + '-message"]').tab('show');
    focus_area.focus();
    focus_area.select();
};

exports.hide = function () {
    $('input, textarea, button').blur();
    $('.message_comp').slideUp(100,
                              function() { $('#compose').css({visibility: "hidden"});});
};

exports.clear = function () {
    $("#compose").find('input[type=text], textarea').val('');
};

exports.set_message_type = function (tabname) {
    is_composing_message = tabname;
    $("#send-status").removeClass(status_classes).hide();
    if (tabname === "stream") {
        $('#personal-message').hide();
        $('#stream-message').show();
        $('#new_message_type').val('stream');
        $("#stream").focus();
    } else {
        $('#personal-message').show();
        $('#stream-message').hide();
        $('#new_message_type').val('personal');
        $("#huddle_recipient").focus();
    }
};

exports.toggle_mode = function () {
    if ($("#message-type-tabs li.active").find("a[href=#stream-message]").length !== 0) {
        // In stream tab, switch to personals.
        exports.show('personal', $("#huddle_recipient"));
    } else {
        exports.show('stream', $("#stream"));
    }
};

exports.composing = function () {
    return is_composing_message;
};

exports.stream_name = function (newval) {
    var oldval = $.trim($("#stream").val());
    if (newval !== undefined) {
        $("#stream").val(newval);
    }
    return oldval;
};

exports.subject = function (newval) {
    var oldval =  $.trim($("#subject").val());
    if (newval !== undefined) {
        $("#subject").val(newval);
    }
    return oldval;
};

exports.message_content = function (newval) {
    var oldval = $.trim($("#new_message_content").val());
    if (newval !== undefined) {
        $("#new_message_content").val(newval);
    }
    return oldval;
};

exports.recipient = function (newval) {
    var oldval = $.trim($("#huddle_recipient").val());
    if (newval !== undefined) {
        $("#huddle_recipient").val(newval);
    }
    return oldval;
};

function compose_error(error_text, bad_input) {
    $('#send-status').removeClass(status_classes)
               .addClass('alert-error')
               .text(error_text)
               .stop(true).fadeTo(0, 1);
    $('#compose').find('input[type="submit"]').removeAttr('disabled');
    bad_input.focus().select();
}

function submit_buttons() {
    return $('#compose').find('input[type="submit"]');
}

// *Synchronously* check if a stream exists.
// If not, displays an error and returns false.
function check_stream_for_send(stream_name) {
    var okay = true;
    $.ajax({
        type: "POST",
        url: "/json/subscriptions/exists",
        data: {'stream': stream_name},
        async: false,
        success: function (data) {
            if (!data.exists) {
                // The stream doesn't exist
                okay = false;
                $('#send-status').removeClass(status_classes).show();
                $('#stream-dne-name').text(stream_name);
                $('#stream-dne').show();
                submit_buttons().removeAttr('disabled');
                exports.hide();
                $('#create-it').focus();
            }
            $("#home-error").hide();
        },
        error: function (xhr) {
            okay = false;
            report_error("Error checking subscription", xhr, $("#home-error"));
            $("#stream").focus();
            submit_buttons().removeAttr('disabled');
        }
    });
    return okay;
}

function validate_stream_message() {
    var stream_name = exports.stream_name();
    if (stream_name === "") {
        compose_error("Please specify a stream", $("#stream"));
        return false;
    }

    if (exports.subject() === "") {
        compose_error("Please specify a subject", $("#subject"));
        return false;
    }

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    if (!subs.have(stream_name)) {
        if (!check_stream_for_send(stream_name)) {
            return false;
        }
        // You're not subbed to the stream
        $('#send-status').removeClass(status_classes).show();
        $('#stream-nosub-name').text(stream_name);
        $('#stream-nosub').show();
        submit_buttons().removeAttr('disabled');
        exports.hide();
        $('#sub-it').focus();
        return false;
    }

    return true;
}

function validate_huddle_message() {
    if (exports.recipient() === "") {
        compose_error("Please specify at least one recipient", $("#huddle_recipient"));
        return false;
    }

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    return true;
}

exports.validate = function () {
    submit_buttons().attr('disabled', 'disabled').blur();

    if (exports.composing() === 'huddle') {
        return validate_huddle_message();
    } else {
        return validate_stream_message();
    }
};

$(function () {
    $("#new_message_content").autosize();
});

return exports;

}());
<commit_msg>Clean up jQuery selectors for the composebox send button.<commit_after>var compose = (function () {

var exports = {};
var is_composing_message = false;

exports.start = function (msg_type, opts) {
    opts = $.extend({ 'message_type': msg_type,
                      'stream': '',
                      'subject': '',
                      'huddle_recipient': '',
                      'message': '' },
                    opts);

    $("#stream").val(opts.stream);
    $("#subject").val(opts.subject);
    $("#huddle_recipient").val(opts.huddle_recipient);
    $("#new_message_content").val(opts.message);

    $('#sidebar a[href="#home"]').tab('show');

    if (msg_type !== 'stream') {
        // TODO: Just to make sure that compose.composing() output is
        // consistent.  We really should just standardize our
        // terminology
        msg_type = "huddle";
    }

    var focus_area;
    if (opts.stream && ! opts.subject) {
        focus_area = 'subject';
    } else if (opts.stream || opts.huddle_recipient) {
        focus_area = 'new_message_content';
    }

    if (msg_type === 'stream') {
        exports.show('stream', $("#" + (focus_area || 'stream')));
    } else {
        exports.show('personal', $("#" + (focus_area || 'huddle_recipient')));
    }

    hotkeys.set_compose();
    is_composing_message = msg_type;
    $(document).trigger($.Event('compose_started.zephyr', opts));
};

exports.cancel = function () {
    compose.hide();
    is_composing_message = false;
    $(document).trigger($.Event('compose_canceled.zephyr'));
};

var send_options;

$(function () {
    var send_status = $('#send-status');

    send_options = {
        dataType: 'json', // This seems to be ignored. We still get back an xhr.
        success: function (resp, statusText, xhr, form) {
            form.find('textarea').val('');
            send_status.hide();
            compose.hide();
            $("#compose-send-button").removeAttr('disabled');
        },
        error: function (xhr, error_type) {
            if (error_type !== 'timeout' && get_updates_params.reload_pending) {
                // The error might be due to the server changing
                reload.initiate({immediate: true, send_after_reload: true});
                return;
            }
            var response = "Error sending message";
            if (xhr.status.toString().charAt(0) === "4") {
                // Only display the error response for 4XX, where we've crafted
                // a nice response.
                response += ": " + $.parseJSON(xhr.responseText).msg;
            }
            send_status.removeClass(status_classes)
                       .addClass('alert-error')
                       .text(response)
                       .append($('<span />')
                           .addClass('send-status-close').html('×')
                           .click(function () { send_status.stop(true).fadeOut(500); }))
                       .stop(true).fadeTo(0,1);

            $("#compose-send-button").removeAttr('disabled');
        }
    };

    send_status.hide();
});

exports.finish = function () {
    if (! compose.validate()) {
        return false;
    }
    $("#compose form").ajaxSubmit(send_options);
    is_composing_message = false;
    $(document).trigger($.Event('compose_finished.zephyr'));
    return true;
};

$(function () {
    $("#compose form").on("submit", function (e) {
       e.preventDefault();
       compose.finish();
    });
});

exports.show = function (tabname, focus_area) {
    if (reload.is_in_progress()) {
        return;
    }
    $("#send-status").removeClass(status_classes).hide();
    $('#compose').css({visibility: "visible"});
    $("#new_message_content").trigger("autosize");
    $('.message_comp').slideDown(100);
    $('#message-type-tabs a[href="#' + tabname + '-message"]').tab('show');
    focus_area.focus();
    focus_area.select();
};

exports.hide = function () {
    $('input, textarea, button').blur();
    $('.message_comp').slideUp(100,
                              function() { $('#compose').css({visibility: "hidden"});});
};

exports.clear = function () {
    $("#compose").find('input[type=text], textarea').val('');
};

exports.set_message_type = function (tabname) {
    is_composing_message = tabname;
    $("#send-status").removeClass(status_classes).hide();
    if (tabname === "stream") {
        $('#personal-message').hide();
        $('#stream-message').show();
        $('#new_message_type').val('stream');
        $("#stream").focus();
    } else {
        $('#personal-message').show();
        $('#stream-message').hide();
        $('#new_message_type').val('personal');
        $("#huddle_recipient").focus();
    }
};

exports.toggle_mode = function () {
    if ($("#message-type-tabs li.active").find("a[href=#stream-message]").length !== 0) {
        // In stream tab, switch to personals.
        exports.show('personal', $("#huddle_recipient"));
    } else {
        exports.show('stream', $("#stream"));
    }
};

exports.composing = function () {
    return is_composing_message;
};

exports.stream_name = function (newval) {
    var oldval = $.trim($("#stream").val());
    if (newval !== undefined) {
        $("#stream").val(newval);
    }
    return oldval;
};

exports.subject = function (newval) {
    var oldval =  $.trim($("#subject").val());
    if (newval !== undefined) {
        $("#subject").val(newval);
    }
    return oldval;
};

exports.message_content = function (newval) {
    var oldval = $.trim($("#new_message_content").val());
    if (newval !== undefined) {
        $("#new_message_content").val(newval);
    }
    return oldval;
};

exports.recipient = function (newval) {
    var oldval = $.trim($("#huddle_recipient").val());
    if (newval !== undefined) {
        $("#huddle_recipient").val(newval);
    }
    return oldval;
};

function compose_error(error_text, bad_input) {
    $('#send-status').removeClass(status_classes)
               .addClass('alert-error')
               .text(error_text)
               .stop(true).fadeTo(0, 1);
    $("#compose-send-button").removeAttr('disabled');
    bad_input.focus().select();
}

// *Synchronously* check if a stream exists.
// If not, displays an error and returns false.
function check_stream_for_send(stream_name) {
    var okay = true;
    $.ajax({
        type: "POST",
        url: "/json/subscriptions/exists",
        data: {'stream': stream_name},
        async: false,
        success: function (data) {
            if (!data.exists) {
                // The stream doesn't exist
                okay = false;
                $('#send-status').removeClass(status_classes).show();
                $('#stream-dne-name').text(stream_name);
                $('#stream-dne').show();
                $("#compose-send-button").removeAttr('disabled');
                exports.hide();
                $('#create-it').focus();
            }
            $("#home-error").hide();
        },
        error: function (xhr) {
            okay = false;
            report_error("Error checking subscription", xhr, $("#home-error"));
            $("#stream").focus();
            $("#compose-send-button").removeAttr('disabled');
        }
    });
    return okay;
}

function validate_stream_message() {
    var stream_name = exports.stream_name();
    if (stream_name === "") {
        compose_error("Please specify a stream", $("#stream"));
        return false;
    }

    if (exports.subject() === "") {
        compose_error("Please specify a subject", $("#subject"));
        return false;
    }

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    if (!subs.have(stream_name)) {
        if (!check_stream_for_send(stream_name)) {
            return false;
        }
        // You're not subbed to the stream
        $('#send-status').removeClass(status_classes).show();
        $('#stream-nosub-name').text(stream_name);
        $('#stream-nosub').show();
        $("#compose-send-button").removeAttr('disabled');
        exports.hide();
        $('#sub-it').focus();
        return false;
    }

    return true;
}

function validate_huddle_message() {
    if (exports.recipient() === "") {
        compose_error("Please specify at least one recipient", $("#huddle_recipient"));
        return false;
    }

    if (exports.message_content() === "") {
        compose_error("You have nothing to send!", $("#new_message_content"));
        return false;
    }

    return true;
}

exports.validate = function () {
    $("#compose-send-button").attr('disabled', 'disabled').blur();

    if (exports.composing() === 'huddle') {
        return validate_huddle_message();
    } else {
        return validate_stream_message();
    }
};

$(function () {
    $("#new_message_content").autosize();
});

return exports;

}());
<|endoftext|>


<commit_before>/**
 * @file Web include helper
 */
/*#ifndef(UMD)*/
"use strict";
/*global _GPF_EVENT_ERROR*/ // gpf.events.EVENT_ERROR
/*global _GPF_EVENT_READY*/ // gpf.events.EVENT_READY
/*global _gpfEventsFire*/ // gpf.events.fire (internal, parameters must match)
/*global _gpfInBrowser*/ // The current host is a browser like
/*global _gpfWebDocument*/ // Browser document object
/*global _gpfWebHead*/ // Browser head tag
/*jshint browser: true*/
/*#endif*/

/* istanbul ignore next */ // Not testable with NodeJS
if (_gpfInBrowser) {

    /**
     * Dynamically loads a script in the browser, wait until the script is loaded to fire the eventsHandler when done.
     *
     * @param {String} url
     * @param {gpf.events.Handler} eventsHandler
     *
     * @eventParam {string} url URL of the included resource
     *
     * @event gpf.events.EVENT_READY
     * The resource has been successfully loaded
     *
     * @event gpf.events.EVENT_ERROR
     * An error occurred when loading the resource
     */
    gpf.web.include = (function () {
        // This is a private context, hence the naming rules are not mandatory here

        var INCLUDE_ID_PREFIX = "gpf-include-",
            // Unique IDs for each include
            lastIncludeId = 0,
            // Dictionary of contexts associated to the includes
            includeMap = {};

        /**
         * Context of an include
         *
         * @param {String} url
         * @param {gpf.events.Handler} eventsHandler
         * @class IncludeContext
         * @constructor
         */
        function IncludeContext (url, eventsHandler) {
            /*jshint validthis:true*/
            this.id = ++lastIncludeId;
            this.url = url;
            this.eventsHandler = eventsHandler;
            includeMap[this.id] = this;
        }

        IncludeContext.prototype = {

            // Unique ID of this context
            id: 0,

            // Include URL
            url: "",

            // @property {gpf.events.Handler} Events handler
            eventsHandler: null,

            /**
             * Clean the include context
             *
             * @param {Object} domScript The script element
             */
            clean: function (domScript) {
                var parent = domScript.parentNode;
                domScript.onerror = domScript.onload = domScript.onreadystatechange = null;
                if (parent) {
                    parent.removeChild(domScript);
                }
                // Destroy context mapping
                delete includeMap[this.id];
            },

            /**
             * The script may be loaded
             *
             * @param {Object} domScript The script element
             */
            check: function (domScript) {
                var readyState = domScript.readyState;
                if (!readyState || -1 < ["loaded", "complete"].indexOf(readyState)) {
                    this.clean(domScript);
                    // IE10: the event is triggered *before* the source is evaluated
                    setTimeout(_gpfEventsFire, 0, _GPF_EVENT_READY, {url: this.url}, this.eventsHandler);
                }
            },

            /**
             * The script loading failed
             *
             * @param {Object} domScript The script element
             */
            failed: function (domScript) {
                this.clean(domScript);
                setTimeout(_gpfEventsFire, 0, _GPF_EVENT_ERROR, {url: this.url}, this.eventsHandler);
            }

        };

        function getIncludeContextFromId (id) {
            return includeMap[id.substr(INCLUDE_ID_PREFIX.length)];
        }

        // Wrapper for the load event
        function onLoad () {
            /*jshint validthis:true*/ // 'this' is the script element
            var me = this; //eslint-disable-line no-invalid-this
            var context = getIncludeContextFromId(me.id);
            if (context) {
                context.check(me);
            }
        }

        // Wrapper for the error event
        function onError () {
            /*jshint validthis:true*/ // 'this' is the script element
            var me = this; //eslint-disable-line no-invalid-this
            var context = getIncludeContextFromId(me.id);
            if (context) {
                context.failed(me);
            }
        }

        /**
         * Use insertBefore instead of appendChild  to avoid an IE6 bug.
         * This arises when a base node is used (#2709 and #4378).
         *
         * @param {Object} domScript
         */
        function insert (domScript) {
            _gpfWebHead.insertBefore(domScript, _gpfWebHead.firstChild);
        }

        /**
         * @inheritdoc gpf.web#include
         * Implementation of gpf.web.include
         *
         * Inspired from http://stackoverflow.com/questions/4845762/
         */
        return function (url, eventsHandler) {
            var context = new IncludeContext(url, eventsHandler),
                domScript = _gpfWebDocument.createElement("script");
            // Configure script tag
            domScript.language = "javascript";
            domScript.src = url;
            domScript.id = INCLUDE_ID_PREFIX + context.id;
            // Attach handlers for all browsers
            domScript.onload = domScript.onreadystatechange = onLoad;
            domScript.onerror = onError;
            // Use async when supported
            if (undefined !== domScript.async) {
                domScript.async = true;
            }
            // Bug in IE10 that loads & triggers immediately, use timeout
            setTimeout(insert, 0, domScript);
        };

    }());

}
<commit_msg>Removes _gpfInBrowser<commit_after>/**
 * @file Web include helper
 */
/*#ifndef(UMD)*/
"use strict";
/*global _GPF_EVENT_ERROR*/ // gpf.events.EVENT_ERROR
/*global _GPF_EVENT_READY*/ // gpf.events.EVENT_READY
/*global _gpfEventsFire*/ // gpf.events.fire (internal, parameters must match)
/*global _gpfHost*/
/*global _GPF_HOST*/
/*global _gpfWebDocument*/ // Browser document object
/*global _gpfWebHead*/ // Browser head tag
/*jshint browser: true*/
/*#endif*/

/* istanbul ignore next */ // Not testable with NodeJS
if (_GPF_HOST.BROWSER === _gpfHost) {

    /**
     * Dynamically loads a script in the browser, wait until the script is loaded to fire the eventsHandler when done.
     *
     * @param {String} url
     * @param {gpf.events.Handler} eventsHandler
     *
     * @eventParam {string} url URL of the included resource
     *
     * @event gpf.events.EVENT_READY
     * The resource has been successfully loaded
     *
     * @event gpf.events.EVENT_ERROR
     * An error occurred when loading the resource
     */
    gpf.web.include = (function () {
        // This is a private context, hence the naming rules are not mandatory here

        var INCLUDE_ID_PREFIX = "gpf-include-",
            // Unique IDs for each include
            lastIncludeId = 0,
            // Dictionary of contexts associated to the includes
            includeMap = {};

        /**
         * Context of an include
         *
         * @param {String} url
         * @param {gpf.events.Handler} eventsHandler
         * @class IncludeContext
         * @constructor
         */
        function IncludeContext (url, eventsHandler) {
            /*jshint validthis:true*/
            this.id = ++lastIncludeId;
            this.url = url;
            this.eventsHandler = eventsHandler;
            includeMap[this.id] = this;
        }

        IncludeContext.prototype = {

            // Unique ID of this context
            id: 0,

            // Include URL
            url: "",

            // @property {gpf.events.Handler} Events handler
            eventsHandler: null,

            /**
             * Clean the include context
             *
             * @param {Object} domScript The script element
             */
            clean: function (domScript) {
                var parent = domScript.parentNode;
                domScript.onerror = domScript.onload = domScript.onreadystatechange = null;
                if (parent) {
                    parent.removeChild(domScript);
                }
                // Destroy context mapping
                delete includeMap[this.id];
            },

            /**
             * The script may be loaded
             *
             * @param {Object} domScript The script element
             */
            check: function (domScript) {
                var readyState = domScript.readyState;
                if (!readyState || -1 < ["loaded", "complete"].indexOf(readyState)) {
                    this.clean(domScript);
                    // IE10: the event is triggered *before* the source is evaluated
                    setTimeout(_gpfEventsFire, 0, _GPF_EVENT_READY, {url: this.url}, this.eventsHandler);
                }
            },

            /**
             * The script loading failed
             *
             * @param {Object} domScript The script element
             */
            failed: function (domScript) {
                this.clean(domScript);
                setTimeout(_gpfEventsFire, 0, _GPF_EVENT_ERROR, {url: this.url}, this.eventsHandler);
            }

        };

        function getIncludeContextFromId (id) {
            return includeMap[id.substr(INCLUDE_ID_PREFIX.length)];
        }

        // Wrapper for the load event
        function onLoad () {
            /*jshint validthis:true*/ // 'this' is the script element
            var me = this; //eslint-disable-line no-invalid-this
            var context = getIncludeContextFromId(me.id);
            if (context) {
                context.check(me);
            }
        }

        // Wrapper for the error event
        function onError () {
            /*jshint validthis:true*/ // 'this' is the script element
            var me = this; //eslint-disable-line no-invalid-this
            var context = getIncludeContextFromId(me.id);
            if (context) {
                context.failed(me);
            }
        }

        /**
         * Use insertBefore instead of appendChild  to avoid an IE6 bug.
         * This arises when a base node is used (#2709 and #4378).
         *
         * @param {Object} domScript
         */
        function insert (domScript) {
            _gpfWebHead.insertBefore(domScript, _gpfWebHead.firstChild);
        }

        /**
         * @inheritdoc gpf.web#include
         * Implementation of gpf.web.include
         *
         * Inspired from http://stackoverflow.com/questions/4845762/
         */
        return function (url, eventsHandler) {
            var context = new IncludeContext(url, eventsHandler),
                domScript = _gpfWebDocument.createElement("script");
            // Configure script tag
            domScript.language = "javascript";
            domScript.src = url;
            domScript.id = INCLUDE_ID_PREFIX + context.id;
            // Attach handlers for all browsers
            domScript.onload = domScript.onreadystatechange = onLoad;
            domScript.onerror = onError;
            // Use async when supported
            if (undefined !== domScript.async) {
                domScript.async = true;
            }
            // Bug in IE10 that loads & triggers immediately, use timeout
            setTimeout(insert, 0, domScript);
        };

    }());

}
<|endoftext|>


<commit_before>const async = require('async');
const Handlebars = require('handlebars');
const render = require('consolidate').handlebars.render;

require('handlebars-helpers').string({
    handlebars: Handlebars
});

const logger = require('../logger');

Handlebars.registerHelper('if_eq', function ifEq(a, b, opts) {
    return a === b
        ? opts.fn(this)
        : opts.inverse(this);
});

Handlebars.registerHelper('unless_eq', function unlessEq(a, b, opts) {
    return a === b
        ? opts.inverse(this)
        : opts.fn(this);
});

module.exports = (files, metalsmith, done) => {

    const keys = Object.keys(files);
    const metadata = Object.assign(metalsmith.metadata(), { cache: false });

    async.each(keys, (file, next) => {
        const str = files[file].contents.toString();
        // do not attempt to render files that do not have mustaches
        if (!/{{([^{}]+)}}/g.test(str)) {
            logger.verbose(`File "${file}" copied`);
            next();
            return;
        }

        render(str, metadata, (err, res) => {
            if (err) {
                err.message = `[${file}] ${err.message}`; //eslint-disable-line no-param-reassign
                logger.fatal(err.message);
                next(err);
                return;
            }
            files[file].contents = new Buffer(res); //eslint-disable-line no-param-reassign
            logger.verbose(`File "${file}" parsed and copied`);
            next();
        });
    }, done);

};<commit_msg>feat(middleware): handlebars helpers in render<commit_after>const async = require('async');
const Handlebars = require('handlebars');
const render = require('consolidate').handlebars.render;

require('handlebars-helpers')({
    handlebars: Handlebars
});

const logger = require('../logger');

Handlebars.registerHelper('if_eq', function ifEq(a, b, opts) {
    return a === b
        ? opts.fn(this)
        : opts.inverse(this);
});

Handlebars.registerHelper('unless_eq', function unlessEq(a, b, opts) {
    return a === b
        ? opts.inverse(this)
        : opts.fn(this);
});

module.exports = (files, metalsmith, done) => {

    const keys = Object.keys(files);
    const metadata = Object.assign(metalsmith.metadata(), { cache: false });

    async.each(keys, (file, next) => {
        const str = files[file].contents.toString();
        // do not attempt to render files that do not have mustaches
        if (!/{{([^{}]+)}}/g.test(str)) {
            logger.verbose(`File "${file}" copied`);
            next();
            return;
        }

        render(str, metadata, (err, res) => {
            if (err) {
                err.message = `[${file}] ${err.message}`; //eslint-disable-line no-param-reassign
                logger.fatal(err.message);
                next(err);
                return;
            }
            files[file].contents = new Buffer(res); //eslint-disable-line no-param-reassign
            logger.verbose(`File "${file}" parsed and copied`);
            next();
        });
    }, done);

};<|endoftext|>


<commit_before>const conventionalCommitsDetector = require('conventional-commits-detector');

async function detectSemanticCommits(config) {
  if (config.semanticCommits !== null) {
    return config.semanticCommits;
  }
  const commitMessages = await platform.getCommitMessages();
  if (commitMessages) {
    commitMessages.length = 10;
  }
  logger.trace(`commitMessages=${JSON.stringify(commitMessages)}`);
  const type = conventionalCommitsDetector(commitMessages);
  logger.debug({ type }, 'Semantic commits detection');
  if (type === 'angular') {
    logger.info('angular semantic commits detected');
    return true;
  }
  logger.info('No semantic commits detected');
  return false;
}

module.exports = {
  detectSemanticCommits,
};
<commit_msg>chore: add debugging to semantic commit detection<commit_after>const conventionalCommitsDetector = require('conventional-commits-detector');

async function detectSemanticCommits(config) {
  logger.debug('detectSemanticCommits()');
  logger.trace({ config });
  if (config.semanticCommits !== null) {
    logger.debug(
      { semanticCommits: config.semanticCommits },
      `semanticCommits already defined`
    );
    return config.semanticCommits;
  }
  const commitMessages = await platform.getCommitMessages();
  if (commitMessages) {
    commitMessages.length = 10;
  }
  logger.trace(`commitMessages=${JSON.stringify(commitMessages)}`);
  const type = conventionalCommitsDetector(commitMessages);
  logger.debug({ type }, 'Semantic commits detection');
  if (type === 'angular') {
    logger.info('angular semantic commits detected');
    return true;
  }
  logger.info('No semantic commits detected');
  return false;
}

module.exports = {
  detectSemanticCommits,
};
<|endoftext|>