nextcloud/apps/files/js/newfilemenu.js

236 lines
6.0 KiB
JavaScript

/*
* Copyright (c) 2014
*
* This file is licensed under the Affero General Public License version 3
* or later.
*
* See the COPYING-README file.
*
*/
/* global Files */
(function() {
var TEMPLATE_MENU =
'<ul>' +
'<li>' +
'<label for="file_upload_start" class="menuitem" data-action="upload" title="{{uploadMaxHumanFilesize}}"><span class="svg icon icon-upload"></span><span class="displayname">{{uploadLabel}}</span></label>' +
'</li>' +
'{{#each items}}' +
'<li>' +
'<a href="#" class="menuitem" data-templatename="{{templateName}}" data-filetype="{{fileType}}" data-action="{{id}}"><span class="icon {{iconClass}} svg"></span><span class="displayname">{{displayName}}</span></a>' +
'</li>' +
'{{/each}}' +
'</ul>';
var TEMPLATE_FILENAME_FORM =
'<form class="filenameform">' +
'<label class="hidden-visually" for="{{cid}}-input-{{fileType}}">{{fileName}}</label>' +
'<input id="{{cid}}-input-{{fileType}}" type="text" value="{{fileName}}">' +
'</form>';
/**
* Construct a new NewFileMenu instance
* @constructs NewFileMenu
*
* @memberof OCA.Files
*/
var NewFileMenu = OC.Backbone.View.extend({
tagName: 'div',
className: 'newFileMenu popovermenu bubble hidden open menu',
events: {
'click .menuitem': '_onClickAction'
},
initialize: function(options) {
var self = this;
var $uploadEl = $('#file_upload_start');
if ($uploadEl.length) {
$uploadEl.on('fileuploadstart', function() {
self.trigger('actionPerformed', 'upload');
});
} else {
console.warn('Missing upload element "file_upload_start"');
}
this._fileList = options && options.fileList;
},
template: function(data) {
if (!OCA.Files.NewFileMenu._TEMPLATE) {
OCA.Files.NewFileMenu._TEMPLATE = Handlebars.compile(TEMPLATE_MENU);
}
return OCA.Files.NewFileMenu._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.hasClass('menuitem')) {
$target = $target.closest('.menuitem');
}
var action = $target.attr('data-action');
// note: clicking the upload label will automatically
// set the focus on the "file_upload_start" hidden field
// which itself triggers the upload dialog.
// Currently the upload logic is still in file-upload.js and filelist.js
if (action === 'upload') {
OC.hideMenus();
} else {
event.preventDefault();
this._promptFileName($target);
}
},
_promptFileName: function($target) {
var self = this;
if (!OCA.Files.NewFileMenu._TEMPLATE_FORM) {
OCA.Files.NewFileMenu._TEMPLATE_FORM = Handlebars.compile(TEMPLATE_FILENAME_FORM);
}
if ($target.find('form').length) {
$target.find('input').focus();
return;
}
// discard other forms
this.$el.find('form').remove();
this.$el.find('.displayname').removeClass('hidden');
$target.find('.displayname').addClass('hidden');
var newName = $target.attr('data-templatename');
var fileType = $target.attr('data-filetype');
var $form = $(OCA.Files.NewFileMenu._TEMPLATE_FORM({
fileName: newName,
cid: this.cid,
fileType: fileType
}));
//this.trigger('actionPerformed', action);
$target.append($form);
// here comes the OLD code
var $input = $form.find('input');
var lastPos;
var checkInput = function () {
var filename = $input.val();
try {
if (!Files.isFileNameValid(filename)) {
// Files.isFileNameValid(filename) throws an exception itself
} else if (self._fileList.inList(filename)) {
throw t('files', '{newname} already exists', {newname: filename});
} else {
return true;
}
} catch (error) {
$input.attr('title', error);
$input.tooltip({placement: 'right', trigger: 'manual'});
$input.tooltip('show');
$input.addClass('error');
}
return false;
};
// verify filename on typing
$input.keyup(function() {
if (checkInput()) {
$input.tooltip('hide');
$input.removeClass('error');
}
});
$input.focus();
// pre select name up to the extension
lastPos = newName.lastIndexOf('.');
if (lastPos === -1) {
lastPos = newName.length;
}
$input.selectRange(0, lastPos);
$form.submit(function(event) {
event.stopPropagation();
event.preventDefault();
if (checkInput()) {
var newname = $input.val();
self._createFile(fileType, newname);
$form.remove();
$target.find('.displayname').removeClass('hidden');
OC.hideMenus();
}
});
},
/**
* Creates a file with the given type and name.
* This calls the matching methods on the attached file list.
*
* @param {string} fileType file type
* @param {string} name file name
*/
_createFile: function(fileType, name) {
switch(fileType) {
case 'file':
this._fileList.createFile(name);
break;
case 'folder':
this._fileList.createDirectory(name);
break;
default:
console.warn('Unknown file type "' + fileType + '"');
}
},
/**
* Renders the menu with the currently set items
*/
render: function() {
this.$el.html(this.template({
uploadMaxHumanFileSize: 'TODO',
uploadLabel: t('files', 'Upload'),
items: [{
id: 'file',
displayName: t('files', 'Text file'),
templateName: t('files', 'New text file.txt'),
iconClass: 'icon-filetype-text',
fileType: 'file'
}, {
id: 'folder',
displayName: t('files', 'Folder'),
templateName: t('files', 'New folder'),
iconClass: 'icon-folder',
fileType: 'folder'
}]
}));
},
/**
* Displays the menu under the given element
*
* @param {Object} $target target element
*/
showAt: function($target) {
this.render();
var targetOffset = $target.offset();
this.$el.css({
left: targetOffset.left,
top: targetOffset.top + $target.height()
});
this.$el.removeClass('hidden');
OC.showMenu(null, this.$el);
}
});
OCA.Files.NewFileMenu = NewFileMenu;
})();