%PDF- %PDF-
Mini Shell

Mini Shell

Direktori : /proc/985914/root/data/old/home/stash/stash/atlassian-stash/static/util/
Upload File :
Create Path :
Current File : //proc/985914/root/data/old/home/stash/stash/atlassian-stash/static/util/handler-registry.js

/** @namespace util/handler-registry */
define('util/handler-registry', [
    'jquery',
    'underscore'
],
/**
 * @example
 * var registry = new require('util/handler-registry');
 *
 * // The consumer determines the options _and_ the expected type of the result
 * registry._handle({type: 'foo'}).done(function(result) {
 *     console.log(result.toUpperCase());
 * });
 *
 * // Register one instance of a handler that conforms to _this_ registry API ('type' on options and returns a string)
 * registry.register({
 *     weight: 200,
 *     handle: function(options) {
 *         return options.type === 'foo' ? "hello" : null;
 *     }
 * });
 *
 * @exports util/handler-registry
 */
    function(
    $,
    _
) {

    'use strict';

    /**
     * Callback to handle a specific type of this type of registry, be it file rendering or something else.
     *
     * @callback HandleCallback
     * @memberOf util/handler-registry
     *
     * @param {util/handler-registry.HandleCallbackOptions} options - Options data provided to handle callback.
     * @return {Promise} A promise object which will hopefully be resolved with a per-registry specific object.
     *                   Returning falsey here is the same as a rejected promise.
     */

    /**
     * @typedef {Object}    Handler
     * @memberOf util/handler-registry
     *
     * @property {number}                               [weight=1000] - Weight of handler determining the order it is tried.
     * @property {util/handler-registry.HandleCallback} handle        - Function called to handle file
     */

    /**
     * The properties of this object are purely determined by the API of the specific registry in use.
     *
     * @typedef {Object}    HandleCallbackOptions
     * @memberOf util/handler-registry
     */

    /**
     * An object that can 'register' objects  to 'handle' a single request, using promises to either
     * resolve or reject, which then passes to the next handler in order (determined by a specified weight).
     *
     * This registry may itself need to be namespaced depending on the requirements. For example there might be a single
     * registry for all the file handlers on a given page, or there might be a registry just for image files.
     *
     * @constructor
     */
    function HandlerRegistry() {
        // List of handlers in this specific registry
        this.handlers = [];
    }

    /**
     * Registers a {@linkcode Handler} for processing requests to the registry.
     *
     * @param {Handler}     handler - Handler to register.
     * @returns {Function}  A function to unregister the given {@linkcode Handler}.
     */
    HandlerRegistry.prototype.register = function(handler) {
        if (!_.isFunction(handler.handle)) {
            throw new Error('Handler must have a handle function');
        }
        handler.weight = typeof handler.weight === 'number' && !isNaN(handler.weight) ? handler.weight : 1000;

        this.handlers.push(handler);
        this.handlers = _.sortBy(this.handlers, function (handler) {
            return handler.weight;
        });
        var that = this;
        return function unregister() {
            var index = that.handlers.indexOf(handler);
            if (index >= 0) {
                that.handlers.splice(index, 1);
            }
        };
    };

    /**
     * Handles a request by calling registered handlers in order of their weight until the request is handled.
     * @param {HandleCallbackOptions}   options - See parameters passed into {@link HandleCallback}.
     * @returns {Promise}   Resolved with an object or rejected if no handler could be found.
     */
    HandlerRegistry.prototype._handle = function(options) {
        var deferred = $.Deferred();
        var aborted;
        var currentResult;

        var handlers = this.handlers;
        var errors = [];
        function next(depth) {
            if (aborted) {
                return deferred.reject(new Error('Handling aborted.'));
            }
            if (depth < handlers.length) {
                // Falsey is handled as reject
                currentResult = handlers[depth].handle(options) || $.Deferred().reject();
                return $.when(currentResult).done(function (data) {
                    deferred.resolve(data || {}, errors);
                }).fail(function(error) {
                    error && errors.push(error);
                    next(depth + 1);
                });
            } else {
                deferred.reject(new Error('No registered handlers were able to handle file'));
            }
        }

        next(0);

        return deferred.promise({
            abort: function() {
                if (!aborted && currentResult && currentResult.abort) {
                    currentResult.abort();
                }
                aborted = true;
            }
        });
    };

    /**
     * Unregisters all handlers.
     */
    HandlerRegistry.prototype._clear = function() {
        this.handlers = [];
    };

    return HandlerRegistry;
});

Zerion Mini Shell 1.0