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

/*
 * The bezier canvas and editing code was adapted from Lea Verou's cubic-bezier project:
 * - https://github.com/LeaVerou/cubic-bezier (cubic-bezier.com)
 *
 * The canvas exceeds the top and bottom of main grid so y-value of points can be
 * dragged outside of the 0-1 range.
 *
 *   . . . . . .
 *   .         .
 *   +---------+
 *   |         |
 *   |         |
 *   |         |
 *   |         |
 *   +---------+ <-- main grid has height of 150
 *   .         .
 *   . . . . . . <-- canvas has height of 300 (extra 75 above/below)
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true,  regexp: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window */

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

    // Brackets modules
    var EditorManager       = brackets.getModule("editor/EditorManager"),
        ExtensionUtils      = brackets.getModule("utils/ExtensionUtils"),
        Strings             = brackets.getModule("strings"),

        InlineBezierCurveEditor = require("InlineBezierCurveEditor").InlineBezierCurveEditor,
        BezierCurveUtils        = require("BezierCurveUtils"),
        EmbeddedStyles          = require("text!EmbeddedStyles.css");

    // Functions

    /**
     * Prepare hostEditor for an InlineBezierCurveEditor at pos if possible.
     * Return editor context if so; otherwise null.
     *
     * @param {Editor} hostEditor
     * @param {{line:Number, ch:Number}} pos
     * @return {?{color:String, start:TextMarker, end:TextMarker}}
     */
    function prepareEditorForProvider(hostEditor, pos) {
        var cursorLine, sel, startPos, endPos, startBookmark, endBookmark, currentMatch,
            cm = hostEditor._codeMirror;

        sel = hostEditor.getSelection();
        if (sel.start.line !== sel.end.line) {
            return null;
        }

        cursorLine = hostEditor.document.getLine(pos.line);

        // code runs several matches complicated patterns, multiple times, so
        // first do a quick, simple check to see make sure we may have a match
        if (!cursorLine.match(/cubic-bezier|linear|ease/)) {
            return null;
        }

        currentMatch = BezierCurveUtils.cubicBezierMatch(cursorLine, false);
        if (!currentMatch) {
            return null;
        }

        // check for subsequent matches, and use first match after pos
        var lineOffset = 0;
        while (pos.ch > (currentMatch.index + currentMatch[0].length + lineOffset)) {
            var restOfLine = cursorLine.substring(currentMatch.index + currentMatch[0].length + lineOffset),
                newMatch = BezierCurveUtils.cubicBezierMatch(restOfLine, false);

            if (newMatch) {
                lineOffset += (currentMatch.index + currentMatch[0].length);
                currentMatch = $.extend(true, [], newMatch);
            } else {
                break;
            }
        }

        currentMatch.lineOffset = lineOffset;

        startPos = {line: pos.line, ch: lineOffset + currentMatch.index};
        endPos   = {line: pos.line, ch: lineOffset + currentMatch.index + currentMatch[0].length};

        startBookmark = cm.setBookmark(startPos);
        endBookmark   = cm.setBookmark(endPos);

        // Adjust selection to the match so that the inline editor won't
        // get dismissed while we're updating the bezier curve.
        hostEditor.setSelection(startPos, endPos);

        return {
            bezierCurve: currentMatch,
            start: startBookmark,
            end: endBookmark
        };
    }

    /**
     * Registered as an inline editor provider: creates an InlineBezierCurveEditor
     * when the cursor is on a bezier curve value.
     *
     * @param {!Editor} hostEditor
     * @param {!{line:Number, ch:Number}} pos
     * @return {?$.Promise} synchronously resolved with an InlineWidget, or null if there's
     *      no color at pos.
     */
    function inlineBezierCurveEditorProvider(hostEditor, pos) {
        var context = prepareEditorForProvider(hostEditor, pos),
            inlineBezierCurveEditor,
            result;

        if (!context) {
            return null;
        } else {
            inlineBezierCurveEditor = new InlineBezierCurveEditor(context.bezierCurve, context.start, context.end);
            inlineBezierCurveEditor.load(hostEditor);

            result = new $.Deferred();
            result.resolve(inlineBezierCurveEditor);
            return result.promise();
        }
    }

    /**
     * Initialization code
     */
    function init() {
        // Load our stylesheet
        ExtensionUtils.loadStyleSheet(module, "main.css");
        ExtensionUtils.addEmbeddedStyleSheet(Mustache.render(EmbeddedStyles, Strings));

        EditorManager.registerInlineEditProvider(inlineBezierCurveEditorProvider);
    }

    init();

    // for use by other InlineColorEditors
    exports.prepareEditorForProvider = prepareEditorForProvider;

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

/*
 * The bezier canvas and editing code was adapted from Lea Verou's cubic-bezier project:
 * - https://github.com/LeaVerou/cubic-bezier (cubic-bezier.com)
 *
 * The canvas exceeds the top and bottom of main grid so y-value of points can be
 * dragged outside of the 0-1 range.
 *
 *   . . . . . .
 *   .         .
 *   +---------+
 *   |         |
 *   |         |
 *   |         |
 *   |         |
 *   +---------+ <-- main grid has height of 150
 *   .         .
 *   . . . . . . <-- canvas has height of 300 (extra 75 above/below)
 *
 */

/*jslint vars: true, plusplus: true, devel: true, nomen: true,  regexp: true, indent: 4, maxerr: 50 */
/*global define, brackets, $, window, Mustache */

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

    // Brackets modules
    var EditorManager       = brackets.getModule("editor/EditorManager"),
        ExtensionUtils      = brackets.getModule("utils/ExtensionUtils"),
        Strings             = brackets.getModule("strings"),

        InlineBezierCurveEditor = require("InlineBezierCurveEditor").InlineBezierCurveEditor,
        BezierCurveUtils        = require("BezierCurveUtils"),
        EmbeddedStyles          = require("text!EmbeddedStyles.css");

    // Functions

    /**
     * Prepare hostEditor for an InlineBezierCurveEditor at pos if possible.
     * Return editor context if so; otherwise null.
     *
     * @param {Editor} hostEditor
     * @param {{line:Number, ch:Number}} pos
     * @return {?{color:String, start:TextMarker, end:TextMarker}}
     */
    function prepareEditorForProvider(hostEditor, pos) {
        var cursorLine, sel, startPos, endPos, startBookmark, endBookmark, currentMatch,
            cm = hostEditor._codeMirror;

        sel = hostEditor.getSelection();
        if (sel.start.line !== sel.end.line) {
            return null;
        }

        cursorLine = hostEditor.document.getLine(pos.line);

        // code runs several matches complicated patterns, multiple times, so
        // first do a quick, simple check to see make sure we may have a match
        if (!cursorLine.match(/cubic-bezier|linear|ease/)) {
            return null;
        }

        currentMatch = BezierCurveUtils.cubicBezierMatch(cursorLine, false);
        if (!currentMatch) {
            return null;
        }

        // check for subsequent matches, and use first match after pos
        var lineOffset = 0;
        while (pos.ch > (currentMatch.index + currentMatch[0].length + lineOffset)) {
            var restOfLine = cursorLine.substring(currentMatch.index + currentMatch[0].length + lineOffset),
                newMatch = BezierCurveUtils.cubicBezierMatch(restOfLine, false);

            if (newMatch) {
                lineOffset += (currentMatch.index + currentMatch[0].length);
                currentMatch = $.extend(true, [], newMatch);
            } else {
                break;
            }
        }

        currentMatch.lineOffset = lineOffset;

        startPos = {line: pos.line, ch: lineOffset + currentMatch.index};
        endPos   = {line: pos.line, ch: lineOffset + currentMatch.index + currentMatch[0].length};

        startBookmark = cm.setBookmark(startPos);
        endBookmark   = cm.setBookmark(endPos);

        // Adjust selection to the match so that the inline editor won't
        // get dismissed while we're updating the bezier curve.
        hostEditor.setSelection(startPos, endPos);

        return {
            bezierCurve: currentMatch,
            start: startBookmark,
            end: endBookmark
        };
    }

    /**
     * Registered as an inline editor provider: creates an InlineBezierCurveEditor
     * when the cursor is on a bezier curve value.
     *
     * @param {!Editor} hostEditor
     * @param {!{line:Number, ch:Number}} pos
     * @return {?$.Promise} synchronously resolved with an InlineWidget, or null if there's
     *      no color at pos.
     */
    function inlineBezierCurveEditorProvider(hostEditor, pos) {
        var context = prepareEditorForProvider(hostEditor, pos),
            inlineBezierCurveEditor,
            result;

        if (!context) {
            return null;
        } else {
            inlineBezierCurveEditor = new InlineBezierCurveEditor(context.bezierCurve, context.start, context.end);
            inlineBezierCurveEditor.load(hostEditor);

            result = new $.Deferred();
            result.resolve(inlineBezierCurveEditor);
            return result.promise();
        }
    }

    /**
     * Initialization code
     */
    function init() {
        // Load our stylesheet
        ExtensionUtils.loadStyleSheet(module, "main.css");
        ExtensionUtils.addEmbeddedStyleSheet(Mustache.render(EmbeddedStyles, Strings));

        EditorManager.registerInlineEditProvider(inlineBezierCurveEditorProvider);
    }

    init();

    // for use by other InlineColorEditors
    exports.prepareEditorForProvider = prepareEditorForProvider;

    // for unit tests only
    exports.inlineBezierCurveEditorProvider = inlineBezierCurveEditorProvider;
});
<|endoftext|>


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

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

    var FileSystemError = brackets.getModule("filesystem/FileSystemError"),
        FileSystemStats = brackets.getModule("filesystem/FileSystemStats");

    var SESSION_START_TIME = new Date();

    /**
     * Create a new file stat. See the FileSystemStats class for more details.
     *
     * @param {!string} fullPath The full path for this File.
     * @return {FileSystemStats} stats.
     */
    function _getStats(uri) {
        return new FileSystemStats({
            isFile: true,
            mtime: SESSION_START_TIME.toISOString(),
            size: 0,
            realPath: uri,
            hash: uri
        });
    }

    /**
     * Model for a RemoteFile.
     *
     * This class should *not* be instantiated directly. Use FileSystem.getFileForPath
     *
     * See the FileSystem class for more details.
     *
     * @constructor
     * @param {!string} fullPath The full path for this File.
     * @param {!FileSystem} fileSystem The file system associated with this File.
     */
    function RemoteFile(protocol, fullPath, fileSystem) {
        this._isFile = true;
        this._isDirectory = false;
        this._path = fullPath;
        this._stat = _getStats(fullPath);
        this._id = fullPath;
        this._name = fullPath.split('/').pop();
        this._fileSystem = fileSystem;
        this.donotWatch = true;
        this.protocol = protocol;
        this.encodedPath = fullPath;
    }

    // Add "fullPath", "name", "parent", "id", "isFile" and "isDirectory" getters
    Object.defineProperties(RemoteFile.prototype, {
        "fullPath": {
            get: function () { return this._path; },
            set: function () { throw new Error("Cannot set fullPath"); }
        },
        "name": {
            get: function () { return this._name; },
            set: function () { throw new Error("Cannot set name"); }
        },
        "parentPath": {
            get: function () { return this._parentPath; },
            set: function () { throw new Error("Cannot set parentPath"); }
        },
        "id": {
            get: function () { return this._id; },
            set: function () { throw new Error("Cannot set id"); }
        },
        "isFile": {
            get: function () { return this._isFile; },
            set: function () { throw new Error("Cannot set isFile"); }
        },
        "isDirectory": {
            get: function () { return this._isDirectory; },
            set: function () { throw new Error("Cannot set isDirectory"); }
        },
        "_impl": {
            get: function () { return this._fileSystem._impl; },
            set: function () { throw new Error("Cannot set _impl"); }
        }
    });

    /**
     * Helpful toString for debugging and equality check purposes
     */
    RemoteFile.prototype.toString = function () {
        return "[RemoteFile " + this._path + "]";
    };

    /**
     * Returns the stats for the remote entry.
     *
     * @param {function (?string, FileSystemStats=)} callback Callback with a
     *      FileSystemError string or FileSystemStats object.
     */
    RemoteFile.prototype.stat = function (callback) {
        if (this._stat) {
            callback(null, this._stat);
        } else {
            callback(FileSystemError.NOT_FOUND);
        }
    };

    RemoteFile.prototype.constructor = RemoteFile;

    /**
     * Cached contents of this file. This value is nullable but should NOT be undefined.
     * @private
     * @type {?string}
     */
    RemoteFile.prototype._contents = null;

    /**
     * @private
     * @type {?string}
     */
    RemoteFile.prototype._encoding = "utf8";

    /**
     * @private
     * @type {?bool}
     */
    RemoteFile.prototype._preserveBOM = false;

    /**
     * Clear any cached data for this file. Note that this explicitly does NOT
     * clear the file's hash.
     * @private
     */
    RemoteFile.prototype._clearCachedData = function () {
        // no-op
    };

    /**
     * Reads a remote file.
     *
     * @param {Object=} options Currently unused.
     * @param {function (?string, string=, FileSystemStats=)} callback Callback that is passed the
     *              FileSystemError string or the file's contents and its stats.
     */
    RemoteFile.prototype.read = function (options, callback) {
        if (typeof (options) === "function") {
            callback = options;
        }
        this._encoding = "utf8";

        if (this._contents !== null && this._stat) {
            callback(null, this._contents, this._encoding, this._stat);
            return;
        }

        var self = this;
        $.ajax({
            url: this.fullPath
        })
        .done(function (data) {
            self._contents = data;
            callback(null, data, self._encoding, self._stat);
        })
        .fail(function (e) {
            callback(FileSystemError.NOT_FOUND);
        });
    };

    /**
     * Write a file.
     *
     * @param {string} data Data to write.
     * @param {object=} options Currently unused.
     * @param {function (?string, FileSystemStats=)=} callback Callback that is passed the
     *              FileSystemError string or the file's new stats.
     */
    RemoteFile.prototype.write = function (data, encoding, callback) {
        if (typeof (encoding) === "function") {
            callback = encoding;
        }
        callback(FileSystemError.NOT_FOUND);
    };

    RemoteFile.prototype.exists = function (callback) {
        callback(null, true);
    };

    RemoteFile.prototype.unlink = function (callback) {
        callback(FileSystemError.NOT_FOUND);
    };

    RemoteFile.prototype.rename = function (newName, callback) {
        callback(FileSystemError.NOT_FOUND);
    };

    RemoteFile.prototype.moveToTrash = function (callback) {
        callback(FileSystemError.NOT_FOUND);
    };

    // Export this class
    module.exports = RemoteFile;
});
<commit_msg>Correcting file name if file path ends with forward slash (#14323)<commit_after>/*
 * Copyright (c) 2018 - present Adobe Systems Incorporated. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 */

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

    var FileSystemError = brackets.getModule("filesystem/FileSystemError"),
        FileSystemStats = brackets.getModule("filesystem/FileSystemStats");

    var SESSION_START_TIME = new Date();

    /**
     * Create a new file stat. See the FileSystemStats class for more details.
     *
     * @param {!string} fullPath The full path for this File.
     * @return {FileSystemStats} stats.
     */
    function _getStats(uri) {
        return new FileSystemStats({
            isFile: true,
            mtime: SESSION_START_TIME.toISOString(),
            size: 0,
            realPath: uri,
            hash: uri
        });
    }

    function _getFileName(filePath) {
        var fileName = filePath.split('/').pop();

        if (!fileName.trim()) {
            fileName = filePath.trim().slice(0, -1);
            fileName = fileName.split('/').pop();
        }

        return fileName;
    }

    /**
     * Model for a RemoteFile.
     *
     * This class should *not* be instantiated directly. Use FileSystem.getFileForPath
     *
     * See the FileSystem class for more details.
     *
     * @constructor
     * @param {!string} fullPath The full path for this File.
     * @param {!FileSystem} fileSystem The file system associated with this File.
     */
    function RemoteFile(protocol, fullPath, fileSystem) {
        this._isFile = true;
        this._isDirectory = false;
        this._path = fullPath;
        this._stat = _getStats(fullPath);
        this._id = fullPath;
        this._name = _getFileName(fullPath);
        this._fileSystem = fileSystem;
        this.donotWatch = true;
        this.protocol = protocol;
        this.encodedPath = fullPath;
    }

    // Add "fullPath", "name", "parent", "id", "isFile" and "isDirectory" getters
    Object.defineProperties(RemoteFile.prototype, {
        "fullPath": {
            get: function () { return this._path; },
            set: function () { throw new Error("Cannot set fullPath"); }
        },
        "name": {
            get: function () { return this._name; },
            set: function () { throw new Error("Cannot set name"); }
        },
        "parentPath": {
            get: function () { return this._parentPath; },
            set: function () { throw new Error("Cannot set parentPath"); }
        },
        "id": {
            get: function () { return this._id; },
            set: function () { throw new Error("Cannot set id"); }
        },
        "isFile": {
            get: function () { return this._isFile; },
            set: function () { throw new Error("Cannot set isFile"); }
        },
        "isDirectory": {
            get: function () { return this._isDirectory; },
            set: function () { throw new Error("Cannot set isDirectory"); }
        },
        "_impl": {
            get: function () { return this._fileSystem._impl; },
            set: function () { throw new Error("Cannot set _impl"); }
        }
    });

    /**
     * Helpful toString for debugging and equality check purposes
     */
    RemoteFile.prototype.toString = function () {
        return "[RemoteFile " + this._path + "]";
    };

    /**
     * Returns the stats for the remote entry.
     *
     * @param {function (?string, FileSystemStats=)} callback Callback with a
     *      FileSystemError string or FileSystemStats object.
     */
    RemoteFile.prototype.stat = function (callback) {
        if (this._stat) {
            callback(null, this._stat);
        } else {
            callback(FileSystemError.NOT_FOUND);
        }
    };

    RemoteFile.prototype.constructor = RemoteFile;

    /**
     * Cached contents of this file. This value is nullable but should NOT be undefined.
     * @private
     * @type {?string}
     */
    RemoteFile.prototype._contents = null;

    /**
     * @private
     * @type {?string}
     */
    RemoteFile.prototype._encoding = "utf8";

    /**
     * @private
     * @type {?bool}
     */
    RemoteFile.prototype._preserveBOM = false;

    /**
     * Clear any cached data for this file. Note that this explicitly does NOT
     * clear the file's hash.
     * @private
     */
    RemoteFile.prototype._clearCachedData = function () {
        // no-op
    };

    /**
     * Reads a remote file.
     *
     * @param {Object=} options Currently unused.
     * @param {function (?string, string=, FileSystemStats=)} callback Callback that is passed the
     *              FileSystemError string or the file's contents and its stats.
     */
    RemoteFile.prototype.read = function (options, callback) {
        if (typeof (options) === "function") {
            callback = options;
        }
        this._encoding = "utf8";

        if (this._contents !== null && this._stat) {
            callback(null, this._contents, this._encoding, this._stat);
            return;
        }

        var self = this;
        $.ajax({
            url: this.fullPath
        })
        .done(function (data) {
            self._contents = data;
            callback(null, data, self._encoding, self._stat);
        })
        .fail(function (e) {
            callback(FileSystemError.NOT_FOUND);
        });
    };

    /**
     * Write a file.
     *
     * @param {string} data Data to write.
     * @param {object=} options Currently unused.
     * @param {function (?string, FileSystemStats=)=} callback Callback that is passed the
     *              FileSystemError string or the file's new stats.
     */
    RemoteFile.prototype.write = function (data, encoding, callback) {
        if (typeof (encoding) === "function") {
            callback = encoding;
        }
        callback(FileSystemError.NOT_FOUND);
    };

    RemoteFile.prototype.exists = function (callback) {
        callback(null, true);
    };

    RemoteFile.prototype.unlink = function (callback) {
        callback(FileSystemError.NOT_FOUND);
    };

    RemoteFile.prototype.rename = function (newName, callback) {
        callback(FileSystemError.NOT_FOUND);
    };

    RemoteFile.prototype.moveToTrash = function (callback) {
        callback(FileSystemError.NOT_FOUND);
    };

    // Export this class
    module.exports = RemoteFile;
});
<|endoftext|>


<commit_before>var userid;

function pageViewModel(gvm) {
    gvm.projecttitle = ko.observable("");
    gvm.userId = -1;
    gvm.coupledCount = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    gvm.addmoduleBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Addmodule");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.coupledLists = ko.observableArray([]);
    gvm.availableLists = ko.observableArray([]);

    gvm.addCoupledList = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.coupledLists.push(tblOject);

        $("#uncouplebtn-" + id).click(function(){
            showYesNoModal("Bent u zeker dat u dit item wil ontkoppelen?", function(val){
                if(val){
                    $.ajax({
                        url: '/api/project/' + $("#projectHeader").data('value') +'/studentlist/uncouple/' + id,
                        type: "DELETE",
                        success: function() {
                            gvm.coupledCount--;
                            viewModel.coupledLists.remove(tblOject);
                        }
                    });

                }
            });
        });
    }

    gvm.addAvailableLists = function(id, name) {
        var tblOject = {tid: id, tname: name};
        gvm.availableLists.push(tblOject);

        $("#couplebtn-" + id).click(function(){
            if(gvm.coupledCount == 0) {
                $.ajax({
                    url: '/api/project/' + $("#projectHeader").data('value') + '/studentlist/' + id,
                    type: "POST",
                    success: function() {
                        gvm.coupledCount++;
                        viewModel.coupledLists.push(tblOject);
                    }
                });
            } else {
                alert("list already coupled");
            }
        });
    }

    gvm.getCoupledLists = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value') + '/coupledlists', function(data) {
            $.each(data, function(i, item) {
                gvm.coupledCount++;
                gvm.addCoupledList(item.id, item.name);
            });
        });
    }

    gvm.getAvailableLists = function() {
        $.getJSON('/api/studentlists/' + gvm.userId, function(data) {
            $.each(data, function(i, item) {
                gvm.addAvailableLists(item.id, item.name);
            });
        });
    }
 }

 function getAllTeachers() {
     var teachers = [];
     $.getJSON('/api/getteacherrapport', function(data) {
        $.each(data, function(i, item) {
            teachers.push(item.firstname + " " + item.lastname);
        });
    });
    return teachers;
 }

function getAllStudentLists() {
    var studentLists = [];
    $.getJSON('/api/studentlistsrapporten/' + userid, function (data) {
        $.each(data, function (i, item) {
            studentLists.push(item.name);
        });
    });
    return studentLists;
}

function getTeacherID($firstname, $lastname) {
    var teacherid = "";
    $.getJSON('/api/teacherID/' + $firstname + '/' + $lastname , function (data) {
        teacherid = item.id;
    });
    console.log(teacherid);
    return teacherid;
}

function getStudentListID($name) {
    var studListid = "";
    $.getJSON('/api/studID/' + userid + '/' + $name, function (data) {
        studListid = item.id;
    });
    console.log(studListid);
    return studListid;
}

 function addGroup($courseid,$studlistid,$teacherid) {
     console.log("Groep toevoegen voor vak " + $courseid);

     var teacherName =  $('#teachersComplete').val();

     var firstname = teacherName.substr(0,teacherName.indexOf(' '));
     var lastname = teacherName.substr(teacherName.indexOf(' ')+1);

     console.log("Voornaam " + firstname);
     console.log("Achternaam " + lastname)

     console.log("Met als studentenlijst  " + $studlistid);

        // console.log(getStudentListID($('#studentListComplete').val()));

     console.log("En als leerkracht  " + $teacherid);
 }

function initPage() {
    viewModel.getProjectInfo();
    viewModel.getCoupledLists();

    //Add Course members

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

    $('#addCoursemembers').click(function() {
        $("#addGroupForm").show();
        $('#teachersComplete').autocomplete({ source: getAllTeachers() });
        $('#studentListComplete').autocomplete({ source: getAllStudentLists() });
    });

    $('#addGroupBtn').click(function() {
         addGroup($('#projectHeader').attr("data-value"),0,0);

        $('addGroupForm').hide();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        userid = data.id;
        viewModel.getAvailableLists(data.id);
    });
}
<commit_msg>methode getIDFromStudentlistByName & getIDFromTeacherByName<commit_after>var userid;

function pageViewModel(gvm) {
    gvm.projecttitle = ko.observable("");
    gvm.userId = -1;
    gvm.coupledCount = 0;

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);

    gvm.addBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("AddBtn")}, gvm);

    gvm.addmoduleBtn = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("Addmodule");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value'), function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.coupledLists = ko.observableArray([]);
    gvm.availableLists = ko.observableArray([]);

    gvm.addCoupledList = function(id, name) {
        // Push data
        var tblOject = {tid: id, tname: name};
        gvm.coupledLists.push(tblOject);

        $("#uncouplebtn-" + id).click(function(){
            showYesNoModal("Bent u zeker dat u dit item wil ontkoppelen?", function(val){
                if(val){
                    $.ajax({
                        url: '/api/project/' + $("#projectHeader").data('value') +'/studentlist/uncouple/' + id,
                        type: "DELETE",
                        success: function() {
                            gvm.coupledCount--;
                            viewModel.coupledLists.remove(tblOject);
                        }
                    });

                }
            });
        });
    }

    gvm.addAvailableLists = function(id, name) {
        var tblOject = {tid: id, tname: name};
        gvm.availableLists.push(tblOject);

        $("#couplebtn-" + id).click(function(){
            if(gvm.coupledCount == 0) {
                $.ajax({
                    url: '/api/project/' + $("#projectHeader").data('value') + '/studentlist/' + id,
                    type: "POST",
                    success: function() {
                        gvm.coupledCount++;
                        viewModel.coupledLists.push(tblOject);
                    }
                });
            } else {
                alert("list already coupled");
            }
        });
    }

    gvm.getCoupledLists = function() {
        $.getJSON('/api/project/' + $("#projectHeader").data('value') + '/coupledlists', function(data) {
            $.each(data, function(i, item) {
                gvm.coupledCount++;
                gvm.addCoupledList(item.id, item.name);
            });
        });
    }

    gvm.getAvailableLists = function() {
        $.getJSON('/api/studentlists/' + gvm.userId, function(data) {
            $.each(data, function(i, item) {
                gvm.addAvailableLists(item.id, item.name);
            });
        });
    }
 }

 function getAllTeachers() {
     var teachers = [];
     $.getJSON('/api/getteacherrapport', function(data) {
        $.each(data, function(i, item) {
            teachers.push(item.firstname + " " + item.lastname);
        });
    });
    return teachers;
 }

function getAllStudentLists() {
    var studentLists = [];
    $.getJSON('/api/studentlistsrapporten/' + userid, function (data) {
        $.each(data, function (i, item) {
            studentLists.push(item.name);
        });
    });
    return studentLists;
}

function getTeacherID($firstname, $lastname) {
    var teacherid = "";
    $.getJSON('/api/teacherID/' + $firstname + '/' + $lastname , function (data) {
        teacherid = item.id;
    });
    console.log(teacherid);
    return teacherid;
}

function getStudentListID($name) {
    var studListid = "";
    $.getJSON('/api/studID/' + userid + '/' + $name, function (data) {
        studListid = item.id;
    });
    console.log(studListid);
    return studListid;
}

 function addGroup($courseid,$studlistid,$teacherid) {
     console.log("Groep toevoegen voor vak " + $courseid);

     //Split selected name on first space
     var teacherName =  $('#teachersComplete').val();
     var firstname = teacherName.substr(0,teacherName.indexOf(' '));
     var lastname = teacherName.substr(teacherName.indexOf(' ')+1);

        console.log(getTeacherID($firstname, $lastname));
        // console.log(getStudentListID($('#studentListComplete').val()));

     console.log("En als leerkracht  " + $teacherid);
 }

function initPage() {
    viewModel.getProjectInfo();
    viewModel.getCoupledLists();

    //Add Course members

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

    $('#addCoursemembers').click(function() {
        $("#addGroupForm").show();
        $('#teachersComplete').autocomplete({ source: getAllTeachers() });
        $('#studentListComplete').autocomplete({ source: getAllStudentLists() });
    });

    $('#addGroupBtn').click(function() {
         addGroup($('#projectHeader').attr("data-value"),0,0);

        $('addGroupForm').hide();
    });

    $.getJSON('/api/currentuser', function(data) {
        viewModel.userId = data.id;
        userid = data.id;
        viewModel.getAvailableLists(data.id);
    });
}
<|endoftext|>


<commit_before>'use strict';

angular.module('msgr')
.factory('subscriptionsService', function($http, apiBaseUrl, authService) {
    return {
        getAll: function() {
            return $http({
                method: 'GET',
                url: apiBaseUrl + '/user/feeds',
                withCredentials: true
            });
        },
        add: function(xmlUrl) {
            return $http({
                method: 'PUT',
                url: apiBaseUrl + '/user/feeds/' + encodeURIComponent(xmlUrl),
                withCredentials: true
            });
        },
        get: function(xmlUrl) {
            return $http({
                method: 'GET',
                url: apiBaseUrl + '/feeds/' + encodeURIComponent(xmlUrl),
                withCredentials: true
            });
        }
    };
});<commit_msg>Updated frontend to take into account API changes<commit_after>'use strict';

angular.module('msgr')
.factory('subscriptionsService', function($http, apiBaseUrl, authService) {
    return {
        getAll: function() {
            return $http({
                method: 'GET',
                url: apiBaseUrl + '/user/feeds',
                withCredentials: true
            });
        },
        add: function(xmlUrl) {
            return $http({
                method: 'PUT',
                url: apiBaseUrl + '/user/feeds/' + encodeURIComponent(xmlUrl),
                withCredentials: true
            });
        },
        get: function(xmlUrl) {
            return $http({
                method: 'GET',
                url: apiBaseUrl + '/user/feeds/' + encodeURIComponent(xmlUrl),
                withCredentials: true
            });
        }
    };
});<|endoftext|>


<commit_before>import { get } from '@vueuse/core';
import store from 'kolibri.coreVue.vuex.store';
import router from 'kolibri.coreVue.router';
import useChannels from '../composables/useChannels';
import useUser from '../composables/useUser';
import useLearnerResources from '../composables/useLearnerResources';
import {
  showTopicsTopic,
  showTopicsChannel,
  showTopicsContent,
} from '../modules/topicsTree/handlers';
import {
  showLibrary,
  showPopularPage,
  showNextStepsPage,
  showResumePage,
} from '../modules/recommended/handlers';
import { showChannels } from '../modules/topicsRoot/handlers';
import { PageNames, ClassesPageNames } from '../constants';
import LibraryPage from '../views/LibraryPage';
import HomePage from '../views/HomePage';
import RecommendedSubpage from '../views/RecommendedSubpage';
import classesRoutes from './classesRoutes';

const { isUserLoggedIn } = useUser();
const { fetchChannels } = useChannels();
const { fetchClasses, fetchResumableContentNodes } = useLearnerResources();

function unassignedContentGuard() {
  const { canAccessUnassignedContent } = store.getters;
  if (!canAccessUnassignedContent) {
    // If there are no memberships and it is allowed, redirect to topics page
    return router.replace({ name: ClassesPageNames.ALL_CLASSES });
  }
  // Otherwise return nothing
  return;
}

export default [
  ...classesRoutes,
  {
    name: PageNames.ROOT,
    path: '/',
    handler: () => {
      return router.replace({ name: PageNames.HOME });
    },
  },
  {
    name: PageNames.HOME,
    path: '/home',
    component: HomePage,
    handler() {
      let promises = [fetchChannels()];
      if (get(isUserLoggedIn)) {
        promises = [...promises, fetchClasses(), fetchResumableContentNodes()];
      }
      return store.dispatch('loading').then(() => {
        return Promise.all(promises)
          .then(() => {
            store.commit('SET_PAGE_NAME', PageNames.HOME);
            store.dispatch('notLoading');
          })
          .catch(error => {
            return store.dispatch('handleApiError', error);
          });
      });
    },
  },
  {
    name: PageNames.LIBRARY,
    path: '/library',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showChannels(store);
      showLibrary(store);
    },
    component: LibraryPage,
  },
  {
    name: PageNames.CONTENT_UNAVAILABLE,
    path: '/resources-unavailable',
    handler: () => {
      store.commit('SET_PAGE_NAME', PageNames.CONTENT_UNAVAILABLE);
      store.commit('CORE_SET_PAGE_LOADING', false);
      store.commit('CORE_SET_ERROR', null);
    },
  },
  {
    name: PageNames.TOPICS_CHANNEL,
    path: '/topics/:channel_id',
    handler: (toRoute, fromRoute) => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      // If navigation is triggered by a custom channel updating the
      // context query param, do not run the handler
      if (toRoute.params.channel_id === fromRoute.params.channel_id) {
        return;
      }
      showTopicsChannel(store, toRoute.params.channel_id);
    },
  },
  {
    name: PageNames.TOPICS_TOPIC,
    path: '/topics/t/:id',
    handler: (toRoute, fromRoute) => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      // If navigation is triggered by a custom navigation updating the
      // context query param, do not run the handler
      if (toRoute.params.id === fromRoute.params.id) {
        return;
      }
      showTopicsTopic(store, { id: toRoute.params.id });
    },
  },
  {
    name: PageNames.TOPICS_CONTENT,
    path: '/topics/c/:id',
    handler: toRoute => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showTopicsContent(store, toRoute.params.id);
    },
  },
  {
    name: PageNames.RECOMMENDED_POPULAR,
    path: '/recommended/popular',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showPopularPage(store);
    },
    component: RecommendedSubpage,
  },
  {
    name: PageNames.RECOMMENDED_RESUME,
    path: '/recommended/resume',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showResumePage(store);
    },
    component: RecommendedSubpage,
  },
  {
    name: PageNames.RECOMMENDED_NEXT_STEPS,
    path: '/recommended/nextsteps',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showNextStepsPage(store);
    },
    component: RecommendedSubpage,
  },
  {
    name: PageNames.BOOKMARKS,
    path: '/bookmarks',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      store.commit('SET_PAGE_NAME', PageNames.BOOKMARKS);
      store.commit('CORE_SET_PAGE_LOADING', false);
    },
  },
  {
    path: '*',
    redirect: '/',
  },
];
<commit_msg>Show resources not available on the home page<commit_after>import { get } from '@vueuse/core';
import store from 'kolibri.coreVue.vuex.store';
import router from 'kolibri.coreVue.router';
import useChannels from '../composables/useChannels';
import useUser from '../composables/useUser';
import useLearnerResources from '../composables/useLearnerResources';
import {
  showTopicsTopic,
  showTopicsChannel,
  showTopicsContent,
} from '../modules/topicsTree/handlers';
import {
  showLibrary,
  showPopularPage,
  showNextStepsPage,
  showResumePage,
} from '../modules/recommended/handlers';
import { showChannels } from '../modules/topicsRoot/handlers';
import { PageNames, ClassesPageNames } from '../constants';
import LibraryPage from '../views/LibraryPage';
import HomePage from '../views/HomePage';
import RecommendedSubpage from '../views/RecommendedSubpage';
import classesRoutes from './classesRoutes';

const { isUserLoggedIn } = useUser();
const { fetchChannels } = useChannels();
const { fetchClasses, fetchResumableContentNodes } = useLearnerResources();

function unassignedContentGuard() {
  const { canAccessUnassignedContent } = store.getters;
  if (!canAccessUnassignedContent) {
    // If there are no memberships and it is allowed, redirect to topics page
    return router.replace({ name: ClassesPageNames.ALL_CLASSES });
  }
  // Otherwise return nothing
  return;
}

export default [
  ...classesRoutes,
  {
    name: PageNames.ROOT,
    path: '/',
    handler: () => {
      return router.replace({ name: PageNames.HOME });
    },
  },
  {
    name: PageNames.HOME,
    path: '/home',
    component: HomePage,
    handler() {
      let promises = [fetchChannels()];
      if (get(isUserLoggedIn)) {
        promises = [...promises, fetchClasses(), fetchResumableContentNodes()];
      }
      return store.dispatch('loading').then(() => {
        return Promise.all(promises)
          .then(([channels]) => {
            if (!channels || !channels.length) {
              router.replace({ name: PageNames.CONTENT_UNAVAILABLE });
              return;
            }
            store.commit('SET_PAGE_NAME', PageNames.HOME);
            store.dispatch('notLoading');
          })
          .catch(error => {
            return store.dispatch('handleApiError', error);
          });
      });
    },
  },
  {
    name: PageNames.LIBRARY,
    path: '/library',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showChannels(store);
      showLibrary(store);
    },
    component: LibraryPage,
  },
  {
    name: PageNames.CONTENT_UNAVAILABLE,
    path: '/resources-unavailable',
    handler: () => {
      store.commit('SET_PAGE_NAME', PageNames.CONTENT_UNAVAILABLE);
      store.commit('CORE_SET_PAGE_LOADING', false);
      store.commit('CORE_SET_ERROR', null);
    },
  },
  {
    name: PageNames.TOPICS_CHANNEL,
    path: '/topics/:channel_id',
    handler: (toRoute, fromRoute) => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      // If navigation is triggered by a custom channel updating the
      // context query param, do not run the handler
      if (toRoute.params.channel_id === fromRoute.params.channel_id) {
        return;
      }
      showTopicsChannel(store, toRoute.params.channel_id);
    },
  },
  {
    name: PageNames.TOPICS_TOPIC,
    path: '/topics/t/:id',
    handler: (toRoute, fromRoute) => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      // If navigation is triggered by a custom navigation updating the
      // context query param, do not run the handler
      if (toRoute.params.id === fromRoute.params.id) {
        return;
      }
      showTopicsTopic(store, { id: toRoute.params.id });
    },
  },
  {
    name: PageNames.TOPICS_CONTENT,
    path: '/topics/c/:id',
    handler: toRoute => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showTopicsContent(store, toRoute.params.id);
    },
  },
  {
    name: PageNames.RECOMMENDED_POPULAR,
    path: '/recommended/popular',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showPopularPage(store);
    },
    component: RecommendedSubpage,
  },
  {
    name: PageNames.RECOMMENDED_RESUME,
    path: '/recommended/resume',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showResumePage(store);
    },
    component: RecommendedSubpage,
  },
  {
    name: PageNames.RECOMMENDED_NEXT_STEPS,
    path: '/recommended/nextsteps',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      showNextStepsPage(store);
    },
    component: RecommendedSubpage,
  },
  {
    name: PageNames.BOOKMARKS,
    path: '/bookmarks',
    handler: () => {
      if (unassignedContentGuard()) {
        return unassignedContentGuard();
      }
      store.commit('SET_PAGE_NAME', PageNames.BOOKMARKS);
      store.commit('CORE_SET_PAGE_LOADING', false);
    },
  },
  {
    path: '*',
    redirect: '/',
  },
];
<|endoftext|>


<commit_before>var mailer = function() {}

mailer.url = "https://mailer.getlantern.org";

mailer.send = function(data) {
	if (typeof data.to == 'undefined') {
		return false;
	}
	if (typeof data.template == 'undefined') {
		return false;
	};
	$.ajax({
		type: "POST",
		url: mailer.url + '/send',
		data: JSON.stringify(data),
		error: function(xhr, s, t) {
			console.log("error", t);
		}
	});
	return true;
};
<commit_msg>Fixing indentation.<commit_after>var mailer = function() {}

mailer.url = "https://mailer.getlantern.org";

mailer.send = function(data) {
  if (typeof data.to == 'undefined') {
    return false;
  }
  if (typeof data.template == 'undefined') {
    return false;
  };
  $.ajax({
    type: "POST",
    url: mailer.url + '/send',
    data: JSON.stringify(data),
    error: function(xhr, s, t) {
      console.log("error", t);
    }
  });
  return true;
};
<|endoftext|>


<commit_before>'use strict';

const request = require('supertest-as-promised');
const integrationTestHelpers = require('./integrationTestHelpers');
const uuid = require('node-uuid');

const instanceUrl = process.env.INSTANCE_URL;
const app = instanceUrl || require('../../src/app');

function getMembersForGroup(someAgent, branchGroup) {
  return function () {
    return someAgent.get(`/branches/${branchGroup.branchId}/members`)
        .then(response => response.body.members);
  };
}

function makeGroup() {
  return {
    name: 'Waiting List',
    description: 'This is a description of the waiting list',
  };
}

function hasGroup(res) {
  const response = res.body;

  if (!(response.id && response.name === 'Waiting List')) {
    throw new Error('created group failed');
  }
}

describe('Groups Integration Test', () => {
  let agent;
  const browserState = {};

  beforeEach(() => {
    agent = request.agent(app);

    return integrationTestHelpers.resetDatabase()
      .then(integrationTestHelpers.createBranch)
      .then(branch => { browserState.branch = branch; return branch; })
      .then(integrationTestHelpers.createBranchAdmin)
      .then(integrationTestHelpers.authenticateBranchAdmin(agent));
  });

  describe('create group for a branch', () => {
    it('should return 200 when the group is successfully created', () => (
      agent.post(`/branches/${browserState.branch.id}/groups`)
        .set('Content-Type', 'application/json')
        .send(makeGroup())
        .expect(200)
        .expect(hasGroup)
    ));

    it('should return 400 if group input data is not valid', () => (
      agent.post(`/branches/${browserState.branch.id}/groups`)
        .set('Content-Type', 'application/json')
        .send({})
        .expect(400)
    ));
  });

  describe('update group', () => {
    it('should return a 200 when the group is successfully updated', () => (
      integrationTestHelpers.createGroupInBranch(browserState.branch.id)
        .tap(integrationTestHelpers.authenticateBranchAdmin(agent))
        .then(branchGroup => agent.put(`/branches/${branchGroup.branchId}/groups/${branchGroup.groupId}`)
          .set('Content-Type', 'application/json')
          .send(makeGroup())
          .expect(200)
          .expect(hasGroup))
    ));
  });

  describe('delete group', () => {
    beforeEach(() => (
      integrationTestHelpers.createGroupInBranch(browserState.branch.id)
        .then(branchGroup => {
          browserState.branchGroup = branchGroup;
        })
    ));

    it('should return a 200 when the group is successfully deleted', () => (
      agent.delete(`/branches/${browserState.branchGroup.branchId}/groups/${browserState.branchGroup.groupId}`)
        .expect(200)
    ));

    it('should return a 200 when a group with members is deleted', () => (
      integrationTestHelpers.createMembers(agent, 2)(browserState.branch)
        .then(getMembersForGroup(agent, browserState.branchGroup))
        .then(integrationTestHelpers.addMembersToGroup(agent, browserState.branchGroup))
        .then(() => agent.delete(`/branches/${browserState.branchGroup.branchId}/groups/${browserState.branchGroup.groupId}`)
        .expect(200))
    ));

    it('should return a 400 if the input data is not valid', () => (
      agent.delete(`/branches/${browserState.branch.id}/groups/whatevs`)
        .expect(400)
    ));

        /* This should return a different code, but requires more work, so will address later*/
    it('should return 500 when trying to delete a group that does not exist', () => (
      agent.delete(`/branches/${browserState.branch.id}/groups/${uuid.v4()}`)
        .expect(500)
    ));
  });
});
<commit_msg>Exclude some group deletion integration tests until we have better kinesis test automation<commit_after>'use strict';

const request = require('supertest-as-promised');
const integrationTestHelpers = require('./integrationTestHelpers');
const uuid = require('node-uuid');

const instanceUrl = process.env.INSTANCE_URL;
const app = instanceUrl || require('../../src/app');

function getMembersForGroup(someAgent, branchGroup) {
  return function () {
    return someAgent.get(`/branches/${branchGroup.branchId}/members`)
        .then(response => response.body.members);
  };
}

function makeGroup() {
  return {
    name: 'Waiting List',
    description: 'This is a description of the waiting list',
  };
}

function hasGroup(res) {
  const response = res.body;

  if (!(response.id && response.name === 'Waiting List')) {
    throw new Error('created group failed');
  }
}

describe('Groups Integration Test', () => {
  let agent;
  const browserState = {};

  beforeEach(() => {
    agent = request.agent(app);

    return integrationTestHelpers.resetDatabase()
      .then(integrationTestHelpers.createBranch)
      .then(branch => { browserState.branch = branch; return branch; })
      .then(integrationTestHelpers.createBranchAdmin)
      .then(integrationTestHelpers.authenticateBranchAdmin(agent));
  });

  describe('create group for a branch', () => {
    it('should return 200 when the group is successfully created', () => (
      agent.post(`/branches/${browserState.branch.id}/groups`)
        .set('Content-Type', 'application/json')
        .send(makeGroup())
        .expect(200)
        .expect(hasGroup)
    ));

    it('should return 400 if group input data is not valid', () => (
      agent.post(`/branches/${browserState.branch.id}/groups`)
        .set('Content-Type', 'application/json')
        .send({})
        .expect(400)
    ));
  });

  describe('update group', () => {
    it('should return a 200 when the group is successfully updated', () => (
      integrationTestHelpers.createGroupInBranch(browserState.branch.id)
        .tap(integrationTestHelpers.authenticateBranchAdmin(agent))
        .then(branchGroup => agent.put(`/branches/${branchGroup.branchId}/groups/${branchGroup.groupId}`)
          .set('Content-Type', 'application/json')
          .send(makeGroup())
          .expect(200)
          .expect(hasGroup))
    ));
  });

  describe('delete group', () => {
    beforeEach(() => (
      integrationTestHelpers.createGroupInBranch(browserState.branch.id)
        .then(branchGroup => {
          browserState.branchGroup = branchGroup;
        })
    ));

    xit('should return a 200 when the group is successfully deleted', () => (
      // Test excluded until we get better docker automation of a local kinesis instance
      agent.delete(`/branches/${browserState.branchGroup.branchId}/groups/${browserState.branchGroup.groupId}`)
        .expect(200)
    ));

    xit('should return a 200 when a group with members is deleted', () => (
      // Test excluded until we get better docker automation of a local kinesis instance
      integrationTestHelpers.createMembers(agent, 2)(browserState.branch)
        .then(getMembersForGroup(agent, browserState.branchGroup))
        .then(integrationTestHelpers.addMembersToGroup(agent, browserState.branchGroup))
        .then(() => agent.delete(`/branches/${browserState.branchGroup.branchId}/groups/${browserState.branchGroup.groupId}`)
        .expect(200))
    ));

    it('should return a 400 if the input data is not valid', () => (
      agent.delete(`/branches/${browserState.branch.id}/groups/whatevs`)
        .expect(400)
    ));

        /* This should return a different code, but requires more work, so will address later*/
    it('should return 500 when trying to delete a group that does not exist', () => (
      agent.delete(`/branches/${browserState.branch.id}/groups/${uuid.v4()}`)
        .expect(500)
    ));
  });
});
<|endoftext|>


<commit_before>'use strict';

const path = require('path');
const browserify = require('browserify');
const derequire = require('derequire');

const bannerTemplate =
  '/*! p5.js v<%= pkg.version %> <%= grunt.template.today("mmmm dd, yyyy") %> */';

module.exports = function(grunt) {
  const srcFilePath = require.resolve('../../src/app.js');

  grunt.registerTask(
    'browserify',
    'Compile the p5.js source with Browserify',
    function(param) {
      const isMin = param === 'min';
      const filename = isMin ? 'p5.pre-min.js' : 'p5.js';

      // This file will not exist until it has been built
      const libFilePath = path.resolve('lib/' + filename);

      // Reading and writing files is asynchronous
      const done = this.async();

      // Render the banner for the top of the file
      const banner = grunt.template.process(bannerTemplate);

      // Invoke Browserify programatically to bundle the code
      let browseified = browserify(srcFilePath, {
        standalone: 'p5'
      });

      if (isMin) {
        browseified = browseified.exclude('../../docs/reference/data.json');
      }

      const bundle = browseified
        .transform('brfs')
        .transform('babelify')
        .bundle();

      // Start the generated output with the banner comment,
      let code = banner + '\n';

      // Then read the bundle into memory so we can run it through derequire
      bundle
        .on('data', function(data) {
          code += data;
        })
        .on('end', function() {
          // "code" is complete: create the distributable UMD build by running
          // the bundle through derequire, then write the bundle to disk.
          // (Derequire changes the bundle's internal "require" function to
          // something that will not interfere with this module being used
          // within a separate browserify bundle.)
          grunt.file.write(libFilePath, derequire(code));

          // Print a success message
          grunt.log.writeln(
            '>>'.green + ' Bundle ' + ('lib/' + filename).cyan + ' created.'
          );

          // Complete the task
          done();
        });
    }
  );
};
<commit_msg>use prettier after derequire<commit_after>'use strict';

const path = require('path');
const browserify = require('browserify');
const prettier = require('prettier');
const derequire = require('derequire');

const bannerTemplate =
  '/*! p5.js v<%= pkg.version %> <%= grunt.template.today("mmmm dd, yyyy") %> */';

module.exports = function(grunt) {
  const srcFilePath = require.resolve('../../src/app.js');

  grunt.registerTask(
    'browserify',
    'Compile the p5.js source with Browserify',
    function(param) {
      const isMin = param === 'min';
      const filename = isMin ? 'p5.pre-min.js' : 'p5.js';

      // This file will not exist until it has been built
      const libFilePath = path.resolve('lib/' + filename);

      // Reading and writing files is asynchronous
      const done = this.async();

      // Render the banner for the top of the file
      const banner = grunt.template.process(bannerTemplate);

      // Invoke Browserify programatically to bundle the code
      let browseified = browserify(srcFilePath, {
        standalone: 'p5'
      });

      if (isMin) {
        browseified = browseified.exclude('../../docs/reference/data.json');
      }

      const bundle = browseified
        .transform('brfs')
        .transform('babelify')
        .bundle();

      // Start the generated output with the banner comment,
      let code = banner + '\n';

      // Then read the bundle into memory so we can run it through derequire
      bundle
        .on('data', function(data) {
          code += data;
        })
        .on('end', function() {
          // "code" is complete: create the distributable UMD build by running
          // the bundle through derequire
          // (Derequire changes the bundle's internal "require" function to
          // something that will not interfere with this module being used
          // within a separate browserify bundle.)
          code = derequire(code);

          // and prettify the code
          if (!isMin) {
            code = prettier.format(code, {
              singleQuote: true
            });
          }

          // finally, write it to disk
          grunt.file.write(libFilePath, code);

          // Print a success message
          grunt.log.writeln(
            '>>'.green + ' Bundle ' + ('lib/' + filename).cyan + ' created.'
          );

          // Complete the task
          done();
        });
    }
  );
};
<|endoftext|>


<commit_before>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var EXPORTED_SYMBOLS = ['PdfStreamConverter'];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
const PDFJS_EVENT_ID = 'pdf.js.message';
const PDF_CONTENT_TYPE = 'application/pdf';
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
const MAX_DATABASE_LENGTH = 4096;

Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/NetUtil.jsm');

let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
                        .getService(Ci.nsIPrivateBrowsingService);
let inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;

function getBoolPref(pref, def) {
  try {
    return Services.prefs.getBoolPref(pref);
  } catch (ex) {
    return def;
  }
}

function setStringPref(pref, value) {
  let str = Cc['@mozilla.org/supports-string;1']
              .createInstance(Ci.nsISupportsString);
  str.data = value;
  Services.prefs.setComplexValue(pref, Ci.nsISupportsString, str);
}

function getStringPref(pref, def) {
  try {
    return Services.prefs.getComplexValue(pref, Ci.nsISupportsString).data;
  } catch (ex) {
    return def;
  }
}

function log(aMsg) {
  if (!getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false))
    return;
  let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
  Services.console.logStringMessage(msg);
  dump(msg + '\n');
}

function getDOMWindow(aChannel) {
  var requestor = aChannel.notificationCallbacks;
  var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
  return win;
}

function getLocalizedStrings(path) {
  var stringBundle = Cc["@mozilla.org/intl/stringbundle;1"].
      getService(Ci.nsIStringBundleService).
      createBundle("chrome://pdfviewer/locale/" + path);

  var map = {};
  var enumerator = stringBundle.getSimpleEnumeration();
  while (enumerator.hasMoreElements()) {
    var string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
    var key = string.key, property = 'textContent';
    var i = key.lastIndexOf('.');
    if (i >= 0) {
      property = key.substring(i + 1);
      key = key.substring(0, i);
    }
    if (!(key in map))
      map[key] = {};
    map[key][property] = string.value;
  }
  return map;
}

// All the priviledged actions.
function ChromeActions() {
  this.inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
}
ChromeActions.prototype = {
  download: function(data) {
    let mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
    var handlerInfo = mimeService.
                        getFromTypeAndExtension('application/pdf', 'pdf');
    var uri = NetUtil.newURI(data);

    var extHelperAppSvc =
          Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
            getService(Ci.nsIExternalHelperAppService);
    var frontWindow = Cc['@mozilla.org/embedcomp/window-watcher;1'].
                        getService(Ci.nsIWindowWatcher).activeWindow;
    var ioService = Services.io;
    var channel = ioService.newChannel(data, null, null);
    var listener = {
      extListener: null,
      onStartRequest: function(aRequest, aContext) {
        this.extListener = extHelperAppSvc.doContent('application/pdf',
                              aRequest, frontWindow, false);
        this.extListener.onStartRequest(aRequest, aContext);
      },
      onStopRequest: function(aRequest, aContext, aStatusCode) {
        if (this.extListener)
          this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
      },
      onDataAvailable: function(aRequest, aContext, aInputStream, aOffset,
                                aCount) {
        this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
                                         aOffset, aCount);
      }
    };

    channel.asyncOpen(listener, null);
  },
  setDatabase: function(data) {
    if (this.inPrivateBrowswing)
      return;
    // Protect against something sending tons of data to setDatabase.
    if (data.length > MAX_DATABASE_LENGTH)
      return;
    setStringPref(EXT_PREFIX + '.database', data);
  },
  getDatabase: function() {
    if (this.inPrivateBrowswing)
      return '{}';
    return getStringPref(EXT_PREFIX + '.database', '{}');
  },
  getLocale: function() {
    return getStringPref('general.useragent.locale', 'en-US');
  },
  getStrings: function(data) {
    try {
      // Lazy initialization of localizedStrings
      if (!('localizedStrings' in this))
        this.localizedStrings = getLocalizedStrings('viewer.properties');

      var result = this.localizedStrings[data];
      return JSON.stringify(result || null)
    } catch (e) {
      log('Unable to retrive localized strings: ' + e);
      return 'null';
    }
  },
  pdfBugEnabled: function() {
    return getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false);
  }
};

// Event listener to trigger chrome privedged code.
function RequestListener(actions) {
  this.actions = actions;
}
// Receive an event and synchronously responds.
RequestListener.prototype.receive = function(event) {
  var message = event.target;
  var action = message.getUserData('action');
  var data = message.getUserData('data');
  var actions = this.actions;
  if (!(action in actions)) {
    log('Unknown action: ' + action);
    return;
  }
  var response = actions[action].call(this.actions, data);
  message.setUserData('response', response, null);
};

function PdfStreamConverter() {
}

PdfStreamConverter.prototype = {

  // properties required for XPCOM registration:
  classID: Components.ID('{6457a96b-2d68-439a-bcfa-44465fbcdbb1}'),
  classDescription: 'pdf.js Component',
  contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',

  QueryInterface: XPCOMUtils.generateQI([
      Ci.nsISupports,
      Ci.nsIStreamConverter,
      Ci.nsIStreamListener,
      Ci.nsIRequestObserver
  ]),

  /*
   * This component works as such:
   * 1. asyncConvertData stores the listener
   * 2. onStartRequest creates a new channel, streams the viewer and cancels
   *    the request so pdf.js can do the request
   * Since the request is cancelled onDataAvailable should not be called. The
   * onStopRequest does nothing. The convert function just returns the stream,
   * it's just the synchronous version of asyncConvertData.
   */

  // nsIStreamConverter::convert
  convert: function(aFromStream, aFromType, aToType, aCtxt) {
    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  },

  // nsIStreamConverter::asyncConvertData
  asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
    // Ignoring HTTP POST requests -- pdf.js has to repeat the request.
    var skipConversion = false;
    try {
      var request = aCtxt;
      request.QueryInterface(Ci.nsIHttpChannel);
      skipConversion = (request.requestMethod !== 'GET');
    } catch (e) {
      // Non-HTTP request... continue normally.
    }
    if (skipConversion)
      throw Cr.NS_ERROR_NOT_IMPLEMENTED;

    // Store the listener passed to us
    this.listener = aListener;
  },

  // nsIStreamListener::onDataAvailable
  onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
    // Do nothing since all the data loading is handled by the viewer.
    log('SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!');
  },

  // nsIRequestObserver::onStartRequest
  onStartRequest: function(aRequest, aContext) {

    // Setup the request so we can use it below.
    aRequest.QueryInterface(Ci.nsIChannel);
    // Cancel the request so the viewer can handle it.
    aRequest.cancel(Cr.NS_BINDING_ABORTED);

    // Create a new channel that is viewer loaded as a resource.
    var ioService = Services.io;
    var channel = ioService.newChannel(
                    'resource://pdf.js/web/viewer.html', null, null);

    var listener = this.listener;
    // Proxy all the request observer calls, when it gets to onStopRequest
    // we can get the dom window.
    var proxy = {
      onStartRequest: function() {
        listener.onStartRequest.apply(listener, arguments);
      },
      onDataAvailable: function() {
        listener.onDataAvailable.apply(listener, arguments);
      },
      onStopRequest: function() {
        var domWindow = getDOMWindow(channel);
        // Double check the url is still the correct one.
        if (domWindow.document.documentURIObject.equals(aRequest.URI)) {
          let requestListener = new RequestListener(new ChromeActions);
          domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
            requestListener.receive(event);
          }, false, true);
        }
        listener.onStopRequest.apply(listener, arguments);
      }
    };

    // Keep the URL the same so the browser sees it as the same.
    channel.originalURI = aRequest.URI;
    channel.asyncOpen(proxy, aContext);
  },

  // nsIRequestObserver::onStopRequest
  onStopRequest: function(aRequest, aContext, aStatusCode) {
    // Do nothing.
  }
};

var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfStreamConverter]);
<commit_msg>Lint errors<commit_after>/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */

'use strict';

var EXPORTED_SYMBOLS = ['PdfStreamConverter'];

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
const PDFJS_EVENT_ID = 'pdf.js.message';
const PDF_CONTENT_TYPE = 'application/pdf';
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
const MAX_DATABASE_LENGTH = 4096;

Cu.import('resource://gre/modules/XPCOMUtils.jsm');
Cu.import('resource://gre/modules/Services.jsm');
Cu.import('resource://gre/modules/NetUtil.jsm');

let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
                        .getService(Ci.nsIPrivateBrowsingService);
let inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;

function getBoolPref(pref, def) {
  try {
    return Services.prefs.getBoolPref(pref);
  } catch (ex) {
    return def;
  }
}

function setStringPref(pref, value) {
  let str = Cc['@mozilla.org/supports-string;1']
              .createInstance(Ci.nsISupportsString);
  str.data = value;
  Services.prefs.setComplexValue(pref, Ci.nsISupportsString, str);
}

function getStringPref(pref, def) {
  try {
    return Services.prefs.getComplexValue(pref, Ci.nsISupportsString).data;
  } catch (ex) {
    return def;
  }
}

function log(aMsg) {
  if (!getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false))
    return;
  let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
  Services.console.logStringMessage(msg);
  dump(msg + '\n');
}

function getDOMWindow(aChannel) {
  var requestor = aChannel.notificationCallbacks;
  var win = requestor.getInterface(Components.interfaces.nsIDOMWindow);
  return win;
}

function getLocalizedStrings(path) {
  var stringBundle = Cc['@mozilla.org/intl/stringbundle;1'].
      getService(Ci.nsIStringBundleService).
      createBundle('chrome://pdfviewer/locale/' + path);

  var map = {};
  var enumerator = stringBundle.getSimpleEnumeration();
  while (enumerator.hasMoreElements()) {
    var string = enumerator.getNext().QueryInterface(Ci.nsIPropertyElement);
    var key = string.key, property = 'textContent';
    var i = key.lastIndexOf('.');
    if (i >= 0) {
      property = key.substring(i + 1);
      key = key.substring(0, i);
    }
    if (!(key in map))
      map[key] = {};
    map[key][property] = string.value;
  }
  return map;
}

// All the priviledged actions.
function ChromeActions() {
  this.inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
}
ChromeActions.prototype = {
  download: function(data) {
    let mimeService = Cc['@mozilla.org/mime;1'].getService(Ci.nsIMIMEService);
    var handlerInfo = mimeService.
                        getFromTypeAndExtension('application/pdf', 'pdf');
    var uri = NetUtil.newURI(data);

    var extHelperAppSvc =
          Cc['@mozilla.org/uriloader/external-helper-app-service;1'].
            getService(Ci.nsIExternalHelperAppService);
    var frontWindow = Cc['@mozilla.org/embedcomp/window-watcher;1'].
                        getService(Ci.nsIWindowWatcher).activeWindow;
    var ioService = Services.io;
    var channel = ioService.newChannel(data, null, null);
    var listener = {
      extListener: null,
      onStartRequest: function(aRequest, aContext) {
        this.extListener = extHelperAppSvc.doContent('application/pdf',
                              aRequest, frontWindow, false);
        this.extListener.onStartRequest(aRequest, aContext);
      },
      onStopRequest: function(aRequest, aContext, aStatusCode) {
        if (this.extListener)
          this.extListener.onStopRequest(aRequest, aContext, aStatusCode);
      },
      onDataAvailable: function(aRequest, aContext, aInputStream, aOffset,
                                aCount) {
        this.extListener.onDataAvailable(aRequest, aContext, aInputStream,
                                         aOffset, aCount);
      }
    };

    channel.asyncOpen(listener, null);
  },
  setDatabase: function(data) {
    if (this.inPrivateBrowswing)
      return;
    // Protect against something sending tons of data to setDatabase.
    if (data.length > MAX_DATABASE_LENGTH)
      return;
    setStringPref(EXT_PREFIX + '.database', data);
  },
  getDatabase: function() {
    if (this.inPrivateBrowswing)
      return '{}';
    return getStringPref(EXT_PREFIX + '.database', '{}');
  },
  getLocale: function() {
    return getStringPref('general.useragent.locale', 'en-US');
  },
  getStrings: function(data) {
    try {
      // Lazy initialization of localizedStrings
      if (!('localizedStrings' in this))
        this.localizedStrings = getLocalizedStrings('viewer.properties');

      var result = this.localizedStrings[data];
      return JSON.stringify(result || null);
    } catch (e) {
      log('Unable to retrive localized strings: ' + e);
      return 'null';
    }
  },
  pdfBugEnabled: function() {
    return getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false);
  }
};

// Event listener to trigger chrome privedged code.
function RequestListener(actions) {
  this.actions = actions;
}
// Receive an event and synchronously responds.
RequestListener.prototype.receive = function(event) {
  var message = event.target;
  var action = message.getUserData('action');
  var data = message.getUserData('data');
  var actions = this.actions;
  if (!(action in actions)) {
    log('Unknown action: ' + action);
    return;
  }
  var response = actions[action].call(this.actions, data);
  message.setUserData('response', response, null);
};

function PdfStreamConverter() {
}

PdfStreamConverter.prototype = {

  // properties required for XPCOM registration:
  classID: Components.ID('{6457a96b-2d68-439a-bcfa-44465fbcdbb1}'),
  classDescription: 'pdf.js Component',
  contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',

  QueryInterface: XPCOMUtils.generateQI([
      Ci.nsISupports,
      Ci.nsIStreamConverter,
      Ci.nsIStreamListener,
      Ci.nsIRequestObserver
  ]),

  /*
   * This component works as such:
   * 1. asyncConvertData stores the listener
   * 2. onStartRequest creates a new channel, streams the viewer and cancels
   *    the request so pdf.js can do the request
   * Since the request is cancelled onDataAvailable should not be called. The
   * onStopRequest does nothing. The convert function just returns the stream,
   * it's just the synchronous version of asyncConvertData.
   */

  // nsIStreamConverter::convert
  convert: function(aFromStream, aFromType, aToType, aCtxt) {
    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
  },

  // nsIStreamConverter::asyncConvertData
  asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
    // Ignoring HTTP POST requests -- pdf.js has to repeat the request.
    var skipConversion = false;
    try {
      var request = aCtxt;
      request.QueryInterface(Ci.nsIHttpChannel);
      skipConversion = (request.requestMethod !== 'GET');
    } catch (e) {
      // Non-HTTP request... continue normally.
    }
    if (skipConversion)
      throw Cr.NS_ERROR_NOT_IMPLEMENTED;

    // Store the listener passed to us
    this.listener = aListener;
  },

  // nsIStreamListener::onDataAvailable
  onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
    // Do nothing since all the data loading is handled by the viewer.
    log('SANITY CHECK: onDataAvailable SHOULD NOT BE CALLED!');
  },

  // nsIRequestObserver::onStartRequest
  onStartRequest: function(aRequest, aContext) {

    // Setup the request so we can use it below.
    aRequest.QueryInterface(Ci.nsIChannel);
    // Cancel the request so the viewer can handle it.
    aRequest.cancel(Cr.NS_BINDING_ABORTED);

    // Create a new channel that is viewer loaded as a resource.
    var ioService = Services.io;
    var channel = ioService.newChannel(
                    'resource://pdf.js/web/viewer.html', null, null);

    var listener = this.listener;
    // Proxy all the request observer calls, when it gets to onStopRequest
    // we can get the dom window.
    var proxy = {
      onStartRequest: function() {
        listener.onStartRequest.apply(listener, arguments);
      },
      onDataAvailable: function() {
        listener.onDataAvailable.apply(listener, arguments);
      },
      onStopRequest: function() {
        var domWindow = getDOMWindow(channel);
        // Double check the url is still the correct one.
        if (domWindow.document.documentURIObject.equals(aRequest.URI)) {
          let requestListener = new RequestListener(new ChromeActions);
          domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
            requestListener.receive(event);
          }, false, true);
        }
        listener.onStopRequest.apply(listener, arguments);
      }
    };

    // Keep the URL the same so the browser sees it as the same.
    channel.originalURI = aRequest.URI;
    channel.asyncOpen(proxy, aContext);
  },

  // nsIRequestObserver::onStopRequest
  onStopRequest: function(aRequest, aContext, aStatusCode) {
    // Do nothing.
  }
};

var NSGetFactory = XPCOMUtils.generateNSGetFactory([PdfStreamConverter]);
<|endoftext|>


<commit_before>'use strict';

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');

var browserSync = require('browser-sync');
var webpack = require('webpack-stream');

var $ = require('gulp-load-plugins')();

function webpackWrapper(watch, callback) {
    var webpackOptions = {
        watch: watch,
        babel: {
            presets: ['es2015']
        },
        module: {
            preLoaders: [{test: /\.js$/, exclude: /node_modules/, loader: 'eslint-loader'}],
            loaders: [{test: /\.js$/, exclude: /node_modules/, loaders: ['ng-annotate', 'babel-loader']}]
        },
        output: {filename: 'index.module.js'}
    };

    if (watch) {
        webpackOptions.devtool = 'inline-source-map';
    }

    var webpackChangeHandler = function (err, stats) {
        if (err) {
            conf.errorHandler('Webpack')(err);
        }
        $.util.log(stats.toString({
            colors: $.util.colors.supportsColor,
            chunks: false,
            hash: false,
            version: false
        }));
        browserSync.reload();
        if (watch) {
            watch = false;
            callback();
        }
    };

    var sources = [path.join(conf.paths.src, '/app/**/*module.js')];

    return gulp.src(sources)
        .pipe(webpack(webpackOptions, null, webpackChangeHandler))
        .pipe(gulp.dest(path.join(conf.paths.tmp, '/serve/app')));
}

gulp.task('scripts', function () {
    return webpackWrapper(false);
});

gulp.task('scripts:watch', function (callback) {
    return webpackWrapper(true, callback);
});<commit_msg>Remove 'watch' condition to generate source-map in gulp:scripts and gulp:scripts watch which are called when calling gulp:serve<commit_after>'use strict';

var path = require('path');
var gulp = require('gulp');
var conf = require('./conf');

var browserSync = require('browser-sync');
var webpack = require('webpack-stream');

var $ = require('gulp-load-plugins')();

function webpackWrapper(watch, callback) {
    var webpackOptions = {
        watch: watch,
        babel: {
            presets: ['es2015']
        },
        module: {
            preLoaders: [{test: /\.js$/, exclude: /node_modules/, loader: 'eslint-loader'}],
            loaders: [{test: /\.js$/, exclude: /node_modules/, loaders: ['ng-annotate', 'babel-loader']}]
        },
        output: {filename: 'index.module.js'}
    };

    webpackOptions.devtool = 'source-map';

    var webpackChangeHandler = function (err, stats) {
        if (err) {
            conf.errorHandler('Webpack')(err);
        }
        $.util.log(stats.toString({
            colors: $.util.colors.supportsColor,
            chunks: false,
            hash: false,
            version: false
        }));
        browserSync.reload();
        if (watch) {
            watch = false;
            callback();
        }
    };

    var sources = [path.join(conf.paths.src, '/app/**/*module.js')];

    return gulp.src(sources)
        .pipe(webpack(webpackOptions, null, webpackChangeHandler))
        .pipe(gulp.dest(path.join(conf.paths.tmp, '/serve/app')));
}

gulp.task('scripts', function () {
    return webpackWrapper(false);
});

gulp.task('scripts:watch', function (callback) {
    return webpackWrapper(true, callback);
});<|endoftext|>