owncloud/core

View on GitHub
apps/files/js/fileactionsmenu.js

Summary

Maintainability
D
1 day
Test Coverage
/*
 * Copyright (c) 2014
 *
 * This file is licensed under the Affero General Public License version 3
 * or later.
 *
 * See the COPYING-README file.
 *
 */

(function() {

    var TEMPLATE_MENU =
        '<ul>' +
        '{{#each items}}' +
        '<li>' +
        '<a href="#" class="menuitem action action-{{nameLowerCase}} permanent" data-action="{{name}}">' +
            '{{#if icon}}<img class="icon" src="{{icon}}"/>' +
            '{{else}}'+
                '{{#if iconClass}}' +
                '<span class="icon {{iconClass}}"></span>' +
                '{{else}}' +
                '<span class="no-icon"></span>' +
                '{{/if}}' +
            '{{/if}}' +
            '<span>{{displayName}}</span></a>' +
        '</li>' +
        '{{/each}}' +
        '</ul>';

    /**
     * Construct a new FileActionsMenu instance
     * @constructs FileActionsMenu
     * @memberof OCA.Files
     */
    var FileActionsMenu = OC.Backbone.View.extend({
        tagName: 'div',
        className: 'fileActionsMenu popovermenu bubble hidden open menu',

        /**
         * Current context
         *
         * @type OCA.Files.FileActionContext
         */
        _context: null,

        events: {
            'click a.action': '_onClickAction'
        },

        template: function(data) {
            if (!OCA.Files.FileActionsMenu._TEMPLATE) {
                OCA.Files.FileActionsMenu._TEMPLATE = Handlebars.compile(TEMPLATE_MENU);
            }
            return OCA.Files.FileActionsMenu._TEMPLATE(data);
        },

        /**
         * Event handler whenever an action has been clicked within the menu
         *
         * @param {Object} event event object
         */
        _onClickAction: function(event) {
            var $target = $(event.target);
            if (!$target.is('a')) {
                $target = $target.closest('a');
            }
            var fileActions = this._context.fileActions;
            var actionName = $target.attr('data-action');
            var actions = fileActions.getActions(
                fileActions.getCurrentMimeType(),
                fileActions.getCurrentType(),
                fileActions.getCurrentPermissions()
            );
            var actionSpec = actions[actionName];
            var fileName = this._context.$file.attr('data-file');

            event.stopPropagation();
            event.preventDefault();

            OC.hideMenus();

            actionSpec.action(
                fileName,
                this._context
            );
        },

        /**
         * Renders the menu with the currently set items
         */
        render: function() {
            var self = this;
            var fileActions = this._context.fileActions;
            var actions = fileActions.getActions(
                fileActions.getCurrentMimeType(),
                fileActions.getCurrentType(),
                fileActions.getCurrentPermissions()
            );

            var defaultActions = fileActions.getDefaultFileActions(
                fileActions.getCurrentMimeType(),
                fileActions.getCurrentType(),
                fileActions.getCurrentPermissions()
            );
            var defaultActionNames = _.map(defaultActions, function(actionSpec) {
                return actionSpec.name;
            });

            actions = fileActions._advancedFilter(actions, this._context);

            // always show default actions for files but not for directories
            var items = _.filter(actions, function(actionSpec) {
                var isDefault = defaultActionNames.indexOf(actionSpec.name) >= 0;
                return (
                    actionSpec.type === OCA.Files.FileActions.TYPE_DROPDOWN &&
                    (!isDefault || fileActions.getCurrentType() !== 'dir')
                );
            });
            items = _.map(items, function(item) {
                if (_.isFunction(item.displayName)) {
                    item = _.extend({}, item);
                    item.displayName = item.displayName(self._context);
                }
                return item;
            });
            items = items.sort(function(actionA, actionB) {
                var orderA = actionA.order || 0;
                var orderB = actionB.order || 0;
                if (orderB === orderA) {
                    return OC.Util.naturalSortCompare(actionA.displayName, actionB.displayName);
                }
                return orderA - orderB;
            });
            items = _.map(items, function(item) {
                item.nameLowerCase = item.name.toLowerCase();
                return item;
            });

            this.$el.html(this.template({
                items: items
            }));
        },

        /**
         * Displays the menu under the given element
         *
         * @param {OCA.Files.FileActionContext} context context
         * @param {Object} $trigger trigger element
         */
        show: function(context) {
            this._context = context;

            this.render();
            this.$el.removeClass('hidden');
            OC.Util.scrollIntoView(this.$el, null);
            OC.showMenu(null, this.$el);
        }
    });

    OCA.Files.FileActionsMenu = FileActionsMenu;

})();