aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/js')
-rw-r--r--apps/files/js/breadcrumb.js5
-rw-r--r--apps/files/js/detailsview.js23
-rw-r--r--apps/files/js/file-upload.js49
-rw-r--r--apps/files/js/fileactions.js19
-rw-r--r--apps/files/js/filelist.js22
-rw-r--r--apps/files/js/filemultiselectmenu.js19
-rw-r--r--apps/files/js/files.js5
-rw-r--r--apps/files/js/filesummary.js19
-rw-r--r--apps/files/js/mainfileinfodetailview.js29
-rw-r--r--apps/files/js/merged-index.json1
-rw-r--r--apps/files/js/navigation.js35
-rw-r--r--apps/files/js/newfilemenu.js29
-rw-r--r--apps/files/js/tagsplugin.js12
-rw-r--r--apps/files/js/templates.js212
-rw-r--r--apps/files/js/templates/detailsview.handlebars12
-rw-r--r--apps/files/js/templates/detailsview.handlebars.js28
-rw-r--r--apps/files/js/templates/favorite_mark.handlebars4
-rw-r--r--apps/files/js/templates/file_action_trigger.handlebars13
-rw-r--r--apps/files/js/templates/filemultiselectmenu.handlebars14
-rw-r--r--apps/files/js/templates/filesummary.handlebars7
-rw-r--r--apps/files/js/templates/mainfileinfodetailsview.handlebars21
-rw-r--r--apps/files/js/templates/newfilemenu.handlebars10
-rw-r--r--apps/files/js/templates/newfilemenu_filename_form.handlebars4
-rw-r--r--apps/files/js/templates/template_addbutton.handlebars4
24 files changed, 411 insertions, 185 deletions
diff --git a/apps/files/js/breadcrumb.js b/apps/files/js/breadcrumb.js
index 319425b67bd..e1193e79b28 100644
--- a/apps/files/js/breadcrumb.js
+++ b/apps/files/js/breadcrumb.js
@@ -178,11 +178,6 @@
$crumb.append(view.$el);
}, this);
- // in case svg is not supported by the browser we need to execute the fallback mechanism
- if (!OC.Util.hasSVGSupport()) {
- OC.Util.replaceSVG(this.$el);
- }
-
// setup drag and drop
if (this.onDrop) {
this.$el.find('.crumb:not(:last-child):not(.crumbmenu), .crumblist:not(:last-child)').droppable({
diff --git a/apps/files/js/detailsview.js b/apps/files/js/detailsview.js
index aed1736693a..2a5d589a730 100644
--- a/apps/files/js/detailsview.js
+++ b/apps/files/js/detailsview.js
@@ -9,22 +9,6 @@
*/
(function() {
- var TEMPLATE =
- ' <div class="detailFileInfoContainer">' +
- ' </div>' +
- ' {{#if tabHeaders}}' +
- ' <ul class="tabHeaders">' +
- ' {{#each tabHeaders}}' +
- ' <li class="tabHeader" data-tabid="{{tabId}}" tabindex="0">' +
- ' <a href="#" tabindex="-1">{{label}}</a>' +
- ' </li>' +
- ' {{/each}}' +
- ' </ul>' +
- ' {{/if}}' +
- ' <div class="tabsContainer">' +
- ' </div>' +
- ' <a class="close icon-close" href="#"><span class="hidden-visually">{{closeLabel}}</span></a>';
-
/**
* @class OCA.Files.DetailsView
* @classdesc
@@ -37,8 +21,6 @@
tabName: 'div',
className: 'detailsView scroll-container',
- _template: null,
-
/**
* List of detail tab views
*
@@ -107,10 +89,7 @@
},
template: function(vars) {
- if (!this._template) {
- this._template = Handlebars.compile(TEMPLATE);
- }
- return this._template(vars);
+ return OCA.Files.Templates['detailsview'](vars);
},
/**
diff --git a/apps/files/js/file-upload.js b/apps/files/js/file-upload.js
index fac086c3da8..9c1e2df53a0 100644
--- a/apps/files/js/file-upload.js
+++ b/apps/files/js/file-upload.js
@@ -402,6 +402,13 @@ OC.Uploader.prototype = _.extend({
_uploads: {},
/**
+ * Count of upload done promises that have not finished yet.
+ *
+ * @type int
+ */
+ _pendingUploadDoneCount: 0,
+
+ /**
* List of directories known to exist.
*
* Key is the fullpath and value is boolean, true meaning that the directory
@@ -745,6 +752,27 @@ OC.Uploader.prototype = _.extend({
});
},
+ _updateProgressBarOnUploadStop: function() {
+ if (this._pendingUploadDoneCount === 0) {
+ // All the uploads ended and there is no pending operation, so hide
+ // the progress bar.
+ // Note that this happens here only with non-chunked uploads; if the
+ // upload was chunked then this will have been executed after all
+ // the uploads ended but before the upload done handler that reduces
+ // the pending operation count was executed.
+ this._hideProgressBar();
+
+ return;
+ }
+
+ $('#uploadprogressbar .label .mobile').text(t('core', '…'));
+ $('#uploadprogressbar .label .desktop').text(t('core', 'Processing files …'));
+
+ // Nothing is being uploaded at this point, and the pending operations
+ // can not be cancelled, so the cancel button should be hidden.
+ $('#uploadprogresswrapper .stop').fadeOut();
+ },
+
_showProgressBar: function() {
$('#uploadprogressbar').fadeIn();
this.$uploadEl.trigger(new $.Event('resized'));
@@ -1126,7 +1154,7 @@ OC.Uploader.prototype = _.extend({
self.log('progress handle fileuploadstop', e, data);
self.clear();
- self._hideProgressBar();
+ self._updateProgressBarOnUploadStop();
self.trigger('stop', e, data);
});
fileupload.on('fileuploadfail', function(e, data) {
@@ -1194,7 +1222,26 @@ OC.Uploader.prototype = _.extend({
});
fileupload.on('fileuploaddone', function(e, data) {
var upload = self.getUpload(data);
+
+ self._pendingUploadDoneCount++;
+
upload.done().then(function() {
+ self._pendingUploadDoneCount--;
+ if (Object.keys(self._uploads).length === 0 && self._pendingUploadDoneCount === 0) {
+ // All the uploads ended and there is no pending
+ // operation, so hide the progress bar.
+ // Note that this happens here only with chunked
+ // uploads; if the upload was non-chunked then this
+ // handler is immediately executed, before the
+ // jQuery upload done handler that removes the
+ // upload from the list, and thus at this point
+ // there is still at least one upload that has not
+ // ended (although the upload stop handler is always
+ // executed after all the uploads have ended, which
+ // hides the progress bar in that case).
+ self._hideProgressBar();
+ }
+
self.trigger('done', e, upload);
}).fail(function(status, response) {
var message = response.message;
diff --git a/apps/files/js/fileactions.js b/apps/files/js/fileactions.js
index 8ce8eddb0b0..5af558d77ba 100644
--- a/apps/files/js/fileactions.js
+++ b/apps/files/js/fileactions.js
@@ -10,17 +10,6 @@
(function() {
- var TEMPLATE_FILE_ACTION_TRIGGER =
- '<a class="action action-{{nameLowerCase}}" href="#" data-action="{{name}}">' +
- '{{#if icon}}' +
- '<img class="svg" alt="{{altText}}" src="{{icon}}" />' +
- '{{else}}' +
- '{{#if iconClass}}<span class="icon {{iconClass}}" />{{/if}}' +
- '{{#unless hasDisplayName}}<span class="hidden-visually">{{altText}}</span>{{/unless}}' +
- '{{/if}}' +
- '{{#if displayName}}<span> {{displayName}}</span>{{/if}}' +
- '</a>';
-
/**
* Construct a new FileActions instance
* @constructs FileActions
@@ -335,11 +324,7 @@
* @param {Object} params action params
*/
_makeActionLink: function(params) {
- if (!this._fileActionTriggerTemplate) {
- this._fileActionTriggerTemplate = Handlebars.compile(TEMPLATE_FILE_ACTION_TRIGGER);
- }
-
- return $(this._fileActionTriggerTemplate(params));
+ return $(OCA.Files.Templates['file_action_trigger'](params));
},
/**
@@ -662,7 +647,7 @@
if (permissions & OC.PERMISSION_UPDATE) {
actions = OC.dialogs.FILEPICKER_TYPE_COPY_MOVE;
}
- OC.dialogs.filepicker(t('files', 'Target folder'), function(targetPath, type) {
+ OC.dialogs.filepicker(t('files', 'Choose target folder'), function(targetPath, type) {
if (type === OC.dialogs.FILEPICKER_TYPE_COPY) {
context.fileList.copy(filename, targetPath, false, context.dir);
}
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js
index 8fb8a021811..94052b10b33 100644
--- a/apps/files/js/filelist.js
+++ b/apps/files/js/filelist.js
@@ -10,11 +10,6 @@
(function() {
- var TEMPLATE_ADDBUTTON = '<a href="#" class="button new">' +
- '<span class="icon {{iconClass}}"></span>' +
- '<span class="hidden-visually">{{addText}}</span>' +
- '</a>';
-
/**
* @class OCA.Files.FileList
* @classdesc
@@ -342,6 +337,14 @@
this.$fileList.on('click','td.filename>a.name, td.filesize, td.date', _.bind(this._onClickFile, this));
+ $.event.trigger({type: "droppedOnTrash"});
+
+ var self=this;
+ this.$fileList.on("droppedOnTrash", function (event, filename, directory) {
+ //self.fileActions.triggerAction('Favorite', self.getModelForFile(file), self);
+ self.do_delete(filename, directory)
+ });
+
this.$fileList.on('change', 'td.selection>.selectCheckBox', _.bind(this._onClickFileCheckbox, this));
this.$el.on('show', _.bind(this._onShow, this));
this.$el.on('urlChanged', _.bind(this._onUrlChanged, this));
@@ -849,7 +852,7 @@
};
var actions = this.isSelectedMovable() ? OC.dialogs.FILEPICKER_TYPE_COPY_MOVE : OC.dialogs.FILEPICKER_TYPE_COPY;
- OC.dialogs.filepicker(t('files', 'Target folder'), function(targetPath, type) {
+ OC.dialogs.filepicker(t('files', 'Choose target folder'), function(targetPath, type) {
self.fileMultiSelectMenu.toggleLoading('copyMove', true);
if (type === OC.dialogs.FILEPICKER_TYPE_COPY) {
self.copy(files, targetPath, disableLoadingState);
@@ -3287,10 +3290,7 @@
if (!$actionsContainer.length || this.$el.find('.button.upload').length) {
return;
}
- if (!this._addButtonTemplate) {
- this._addButtonTemplate = Handlebars.compile(TEMPLATE_ADDBUTTON);
- }
- var $newButton = $(this._addButtonTemplate({
+ var $newButton = $(OCA.Files.Templates['template_addbutton']({
addText: t('files', 'New'),
iconClass: 'icon-add'
}));
@@ -3432,7 +3432,7 @@
$(document).ready(function() {
// FIXME: unused ?
OCA.Files.FileList.useUndo = (window.onbeforeunload)?true:false;
- $(window).bind('beforeunload', function () {
+ $(window).on('beforeunload', function () {
if (OCA.Files.FileList.lastAction) {
OCA.Files.FileList.lastAction();
}
diff --git a/apps/files/js/filemultiselectmenu.js b/apps/files/js/filemultiselectmenu.js
index d587d1fbdb2..d50fe28eace 100644
--- a/apps/files/js/filemultiselectmenu.js
+++ b/apps/files/js/filemultiselectmenu.js
@@ -9,21 +9,6 @@
*/
(function() {
- var TEMPLATE_MENU =
- '<ul>' +
- '{{#each items}}' +
- '<li class="item-{{name}}">' +
- '<a href="#" class="menuitem action {{name}} permanent" data-action="{{name}}">' +
- '{{#if iconClass}}' +
- '<span class="icon {{iconClass}}"></span>' +
- '{{else}}' +
- '<span class="no-icon"></span>' +
- '{{/if}}' +
- '<span class="label">{{displayName}}</span>' +
- '</a></li>' +
- '{{/each}}' +
- '</ul>';
-
var FileMultiSelectMenu = OC.Backbone.View.extend({
tagName: 'div',
className: 'filesSelectMenu popovermenu bubble menu-center',
@@ -34,12 +19,12 @@
events: {
'click a.action': '_onClickAction'
},
- template: Handlebars.compile(TEMPLATE_MENU),
+
/**
* Renders the menu with the currently set items
*/
render: function() {
- this.$el.html(this.template({
+ this.$el.html(OCA.Files.Templates['filemultiselectmenu']({
items: this._scopes
}));
},
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 094fb81d78b..016aef05a96 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -506,10 +506,5 @@ var folderDropOptions = {
tolerance: 'pointer'
};
-// override core's fileDownloadPath (legacy)
-function fileDownloadPath(dir, file) {
- return OCA.Files.Files.getDownloadUrl(file, dir);
-}
-
// for backward compatibility
window.Files = OCA.Files.Files;
diff --git a/apps/files/js/filesummary.js b/apps/files/js/filesummary.js
index 7545654ec44..c866ccb4ff5 100644
--- a/apps/files/js/filesummary.js
+++ b/apps/files/js/filesummary.js
@@ -20,15 +20,6 @@
*/
(function() {
- var INFO_TEMPLATE =
- '<span class="info">' +
- '<span class="dirinfo"></span>' +
- '<span class="connector">{{connectorLabel}}</span>' +
- '<span class="fileinfo"></span>' +
- '<span class="hiddeninfo"></span>' +
- '<span class="filter"></span>' +
- '</span>';
-
/**
* The FileSummary class encapsulates the file summary values and
* the logic to render it in the given container
@@ -200,10 +191,12 @@
},
_infoTemplate: function(data) {
- if (!this._infoTemplateCompiled) {
- this._infoTemplateCompiled = Handlebars.compile(INFO_TEMPLATE);
- }
- return this._infoTemplateCompiled(_.extend({
+ /* NOTE: To update the template make changes in filesummary.handlebars
+ * and run:
+ *
+ * handlebars -n OCA.Files.FileSummary.Templates filesummary.handlebars -f filesummary_template.js
+ */
+ return OCA.Files.Templates['filesummary'](_.extend({
connectorLabel: t('files', '{dirs} and {files}', {dirs: '', files: ''})
}, data));
},
diff --git a/apps/files/js/mainfileinfodetailview.js b/apps/files/js/mainfileinfodetailview.js
index 626ab86ded3..4a2067e09e5 100644
--- a/apps/files/js/mainfileinfodetailview.js
+++ b/apps/files/js/mainfileinfodetailview.js
@@ -9,29 +9,6 @@
*/
(function() {
- var TEMPLATE =
- '<div class="thumbnailContainer"><a href="#" class="thumbnail action-default"><div class="stretcher"/></a></div>' +
- '<div class="file-details-container">' +
- '<div class="fileName">' +
- '<h3 title="{{name}}" class="ellipsis">{{name}}</h3>' +
- '<a class="permalink" href="{{permalink}}" title="{{permalinkTitle}}" data-clipboard-text="{{permalink}}">' +
- '<span class="icon icon-clippy"></span>' +
- '<span class="hidden-visually">{{permalinkTitle}}</span>' +
- '</a>' +
- '</div>' +
- ' <div class="file-details ellipsis">' +
- ' {{#if hasFavoriteAction}}' +
- ' <a href="#" class="action action-favorite favorite permanent">' +
- ' <span class="icon {{starClass}}" title="{{starAltText}}"></span>' +
- ' </a>' +
- ' {{/if}}' +
- ' {{#if hasSize}}<span class="size" title="{{altSize}}">{{size}}</span>, {{/if}}<span class="date live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</span>' +
- ' </div>' +
- '</div>' +
- '<div class="hidden permalink-field">' +
- '<input type="text" value="{{permalink}}" placeholder="{{permalinkTitle}}" readonly="readonly"/>' +
- '</div>';
-
/**
* @class OCA.Files.MainFileInfoDetailView
* @classdesc
@@ -71,10 +48,7 @@
},
template: function(data) {
- if (!this._template) {
- this._template = Handlebars.compile(TEMPLATE);
- }
- return this._template(data);
+ return OCA.Files.Templates['mainfileinfodetailsview'](data);
},
initialize: function(options) {
@@ -213,7 +187,6 @@
} else {
var iconUrl = this.model.get('icon') || OC.MimeType.getIconUrl('dir');
$iconDiv.css('background-image', 'url("' + iconUrl + '")');
- OC.Util.scaleFixForIE8($iconDiv);
}
this.$el.find('[title]').tooltip({placement: 'bottom'});
} else {
diff --git a/apps/files/js/merged-index.json b/apps/files/js/merged-index.json
index cd7e72e1a51..e891d10bdae 100644
--- a/apps/files/js/merged-index.json
+++ b/apps/files/js/merged-index.json
@@ -1,5 +1,6 @@
[
"app.js",
+ "templates.js",
"file-upload.js",
"newfilemenu.js",
"jquery.fileupload.js",
diff --git a/apps/files/js/navigation.js b/apps/files/js/navigation.js
index 9fc2180c923..b3648fedc6c 100644
--- a/apps/files/js/navigation.js
+++ b/apps/files/js/navigation.js
@@ -64,6 +64,41 @@
_setupEvents: function () {
this.$el.on('click', 'li a', _.bind(this._onClickItem, this))
this.$el.on('click', 'li button', _.bind(this._onClickMenuButton, this));
+
+ var trashElement=$(".nav-trashbin");
+
+ //this div is required to prefetch the icon, otherwise it takes a second to show up
+ trashElement.append("<div class='nav-icon-trashbin-starred'></div>")
+ trashElement.droppable({
+ over: function( event, ui ) {
+ trashElement.addClass('dropzone-background')
+ },
+ out: function( event, ui ) {
+ trashElement.removeClass('dropzone-background');
+ },
+ activate: function( event, ui ) {
+ var elem=trashElement.find("a").first();
+ elem.addClass('nav-icon-trashbin-starred').removeClass('nav-icon-trashbin');
+ },
+ deactivate: function( event, ui ) {
+ var elem=trashElement.find("a").first();
+ elem.addClass('nav-icon-trashbin').removeClass('nav-icon-trashbin-starred');
+ },
+ drop: function( event, ui ) {
+
+ var $selectedFiles = $(ui.draggable);
+
+ if (ui.helper.find("tr").size()===1) {
+ var $tr = $selectedFiles.closest('tr');
+ $selectedFiles.trigger("droppedOnTrash", $tr.attr("data-file"), $tr.attr('data-dir'));
+ }else{
+ var item = ui.helper.find("tr");
+ for(var i=0; i<item.length;i++){
+ $selectedFiles.trigger("droppedOnTrash", item[i].getAttribute("data-file"), item[i].getAttribute("data-dir"));
+ }
+ }
+ }
+ });
},
/**
diff --git a/apps/files/js/newfilemenu.js b/apps/files/js/newfilemenu.js
index 0ad7312c985..01a183a33a7 100644
--- a/apps/files/js/newfilemenu.js
+++ b/apps/files/js/newfilemenu.js
@@ -12,24 +12,6 @@
(function() {
- var TEMPLATE_MENU =
- '<ul>' +
- '<li>' +
- '<label for="file_upload_start" class="menuitem" data-action="upload" title="{{uploadMaxHumanFilesize}}" tabindex="0"><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">' +
- '<input id="{{cid}}-input-{{fileType}}" type="text" value="{{fileName}}" autocomplete="off" autocapitalize="off">' +
- '<input type="submit" value=" " class="icon-confirm" />'
- '</form>';
-
/**
* Construct a new NewFileMenu instance
* @constructs NewFileMenu
@@ -78,10 +60,7 @@
},
template: function(data) {
- if (!OCA.Files.NewFileMenu._TEMPLATE) {
- OCA.Files.NewFileMenu._TEMPLATE = Handlebars.compile(TEMPLATE_MENU);
- }
- return OCA.Files.NewFileMenu._TEMPLATE(data);
+ return OCA.Files.Templates['newfilemenu'](data);
},
/**
@@ -111,9 +90,6 @@
_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[type=\'text\']').focus();
@@ -128,7 +104,7 @@
var newName = $target.attr('data-templatename');
var fileType = $target.attr('data-filetype');
- var $form = $(OCA.Files.NewFileMenu._TEMPLATE_FORM({
+ var $form = $(OCA.Files.Templates['newfilemenu_filename_form']({
fileName: newName,
cid: this.cid,
fileType: fileType
@@ -234,7 +210,6 @@
uploadLabel: t('files', 'Upload file'),
items: this._menuItems
}));
- OC.Util.scaleFixForIE8(this.$('.svg'));
// Trigger upload action also with keyboard navigation on enter
this.$el.find('[for="file_upload_start"]').on('keyup', function(event) {
diff --git a/apps/files/js/tagsplugin.js b/apps/files/js/tagsplugin.js
index 4ce6604384d..b8e17115b4b 100644
--- a/apps/files/js/tagsplugin.js
+++ b/apps/files/js/tagsplugin.js
@@ -17,13 +17,6 @@
PROPERTY_FAVORITE: '{' + OC.Files.Client.NS_OWNCLOUD + '}favorite'
});
- var TEMPLATE_FAVORITE_MARK =
- '<div ' +
- 'class="favorite-mark {{#isFavorite}}permanent{{/isFavorite}}">' +
- '<span class="icon {{iconClass}}" />' +
- '<span class="hidden-visually">{{altText}}</span>' +
- '</div>';
-
/**
* Returns the icon class for the matching state
*
@@ -41,10 +34,7 @@
* @return {Object} jQuery object
*/
function renderStar (state) {
- if (!this._template) {
- this._template = Handlebars.compile(TEMPLATE_FAVORITE_MARK);
- }
- return this._template({
+ return OCA.Files.Templates['favorite_mark']({
isFavorite: state,
altText: state ? t('files', 'Favorited') : t('files', 'Not favorited'),
iconClass: getStarIconClass(state)
diff --git a/apps/files/js/templates.js b/apps/files/js/templates.js
new file mode 100644
index 00000000000..f05959ff985
--- /dev/null
+++ b/apps/files/js/templates.js
@@ -0,0 +1,212 @@
+(function() {
+ var template = Handlebars.template, templates = OCA.Files.Templates = OCA.Files.Templates || {};
+templates['detailsview'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var stack1;
+
+ return "<ul class=\"tabHeaders\">\n"
+ + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.tabHeaders : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "</ul>\n";
+},"2":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <li class=\"tabHeader\" data-tabid=\""
+ + alias4(((helper = (helper = helpers.tabId || (depth0 != null ? depth0.tabId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"tabId","hash":{},"data":data}) : helper)))
+ + "\" tabindex=\"0\">\n <a href=\"#\" tabindex=\"-1\">"
+ + alias4(((helper = (helper = helpers.label || (depth0 != null ? depth0.label : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"label","hash":{},"data":data}) : helper)))
+ + "</a>\n </li>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {});
+
+ return "<div class=\"detailFileInfoContainer\"></div>\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.tabHeaders : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "<div class=\"tabsContainer\"></div>\n<a class=\"close icon-close\" href=\"#\"><span class=\"hidden-visually\">"
+ + container.escapeExpression(((helper = (helper = helpers.closeLabel || (depth0 != null ? depth0.closeLabel : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(alias1,{"name":"closeLabel","hash":{},"data":data}) : helper)))
+ + "</span></a>\n";
+},"useData":true});
+templates['favorite_mark'] = template({"1":function(container,depth0,helpers,partials,data) {
+ return "permanent";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, options, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression, buffer =
+ "<div class=\"favorite-mark ";
+ stack1 = ((helper = (helper = helpers.isFavorite || (depth0 != null ? depth0.isFavorite : depth0)) != null ? helper : alias2),(options={"name":"isFavorite","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data}),(typeof helper === alias3 ? helper.call(alias1,options) : helper));
+ if (!helpers.isFavorite) { stack1 = helpers.blockHelperMissing.call(depth0,stack1,options)}
+ if (stack1 != null) { buffer += stack1; }
+ return buffer + "\">\n <span class=\"icon "
+ + alias4(((helper = (helper = helpers.iconClass || (depth0 != null ? depth0.iconClass : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"iconClass","hash":{},"data":data}) : helper)))
+ + "\" />\n <span class=\"hidden-visually\">"
+ + alias4(((helper = (helper = helpers.altText || (depth0 != null ? depth0.altText : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"altText","hash":{},"data":data}) : helper)))
+ + "</span>\n</div>\n";
+},"useData":true});
+templates['file_action_trigger'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <img class=\"svg\" alt=\""
+ + alias4(((helper = (helper = helpers.altText || (depth0 != null ? depth0.altText : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"altText","hash":{},"data":data}) : helper)))
+ + "\" src=\""
+ + alias4(((helper = (helper = helpers.icon || (depth0 != null ? depth0.icon : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"icon","hash":{},"data":data}) : helper)))
+ + "\" />\n";
+},"3":function(container,depth0,helpers,partials,data) {
+ var stack1, alias1=depth0 != null ? depth0 : (container.nullContext || {});
+
+ return ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.iconClass : depth0),{"name":"if","hash":{},"fn":container.program(4, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + ((stack1 = helpers.unless.call(alias1,(depth0 != null ? depth0.hasDisplayName : depth0),{"name":"unless","hash":{},"fn":container.program(6, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "");
+},"4":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return " <span class=\"icon "
+ + container.escapeExpression(((helper = (helper = helpers.iconClass || (depth0 != null ? depth0.iconClass : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"iconClass","hash":{},"data":data}) : helper)))
+ + "\" />\n";
+},"6":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return " <span class=\"hidden-visually\">"
+ + container.escapeExpression(((helper = (helper = helpers.altText || (depth0 != null ? depth0.altText : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"altText","hash":{},"data":data}) : helper)))
+ + "</span>\n";
+},"8":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return "<span> "
+ + container.escapeExpression(((helper = (helper = helpers.displayName || (depth0 != null ? depth0.displayName : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"displayName","hash":{},"data":data}) : helper)))
+ + "</span>";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<a class=\"action action-"
+ + alias4(((helper = (helper = helpers.nameLowerCase || (depth0 != null ? depth0.nameLowerCase : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"nameLowerCase","hash":{},"data":data}) : helper)))
+ + "\" href=\"#\" data-action=\""
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "\">\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.icon : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.program(3, data, 0),"data":data})) != null ? stack1 : "")
+ + " "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.displayName : depth0),{"name":"if","hash":{},"fn":container.program(8, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "\n</a>\n";
+},"useData":true});
+templates['filemultiselectmenu'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <li class=\"item-"
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "\">\n <a href=\"#\" class=\"menuitem action "
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + " permanent\" data-action=\""
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "\">\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.iconClass : depth0),{"name":"if","hash":{},"fn":container.program(2, data, 0),"inverse":container.program(4, data, 0),"data":data})) != null ? stack1 : "")
+ + " <span class=\"label\">"
+ + alias4(((helper = (helper = helpers.displayName || (depth0 != null ? depth0.displayName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"displayName","hash":{},"data":data}) : helper)))
+ + "</span>\n </a>\n </li>\n";
+},"2":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return " <span class=\"icon "
+ + container.escapeExpression(((helper = (helper = helpers.iconClass || (depth0 != null ? depth0.iconClass : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"iconClass","hash":{},"data":data}) : helper)))
+ + "\"></span>\n";
+},"4":function(container,depth0,helpers,partials,data) {
+ return " <span class=\"no-icon\"></span>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1;
+
+ return "<ul>\n"
+ + ((stack1 = helpers.each.call(depth0 != null ? depth0 : (container.nullContext || {}),(depth0 != null ? depth0.items : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "</ul>\n";
+},"useData":true});
+templates['filesummary'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var helper;
+
+ return "<span class=\"info\">\n <span class=\"dirinfo\"></span>\n <span class=\"connector\">"
+ + container.escapeExpression(((helper = (helper = helpers.connectorLabel || (depth0 != null ? depth0.connectorLabel : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"connectorLabel","hash":{},"data":data}) : helper)))
+ + "</span>\n <span class=\"fileinfo\"></span>\n <span class=\"hiddeninfo\"></span>\n <span class=\"filter\"></span>\n</span>\n";
+},"useData":true});
+templates['mainfileinfodetailsview'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <a href=\"#\" class=\"action action-favorite favorite permanent\">\n <span class=\"icon "
+ + alias4(((helper = (helper = helpers.starClass || (depth0 != null ? depth0.starClass : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"starClass","hash":{},"data":data}) : helper)))
+ + "\" title=\""
+ + alias4(((helper = (helper = helpers.starAltText || (depth0 != null ? depth0.starAltText : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"starAltText","hash":{},"data":data}) : helper)))
+ + "\"></span>\n </a>\n";
+},"3":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<span class=\"size\" title=\""
+ + alias4(((helper = (helper = helpers.altSize || (depth0 != null ? depth0.altSize : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"altSize","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.size || (depth0 != null ? depth0.size : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"size","hash":{},"data":data}) : helper)))
+ + "</span>, ";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<div class=\"thumbnailContainer\"><a href=\"#\" class=\"thumbnail action-default\"><div class=\"stretcher\"/></a></div>\n<div class=\"file-details-container\">\n <div class=\"fileName\">\n <h3 title=\""
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "\" class=\"ellipsis\">"
+ + alias4(((helper = (helper = helpers.name || (depth0 != null ? depth0.name : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"name","hash":{},"data":data}) : helper)))
+ + "</h3>\n <a class=\"permalink\" href=\""
+ + alias4(((helper = (helper = helpers.permalink || (depth0 != null ? depth0.permalink : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"permalink","hash":{},"data":data}) : helper)))
+ + "\" title=\""
+ + alias4(((helper = (helper = helpers.permalinkTitle || (depth0 != null ? depth0.permalinkTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"permalinkTitle","hash":{},"data":data}) : helper)))
+ + "\" data-clipboard-text=\""
+ + alias4(((helper = (helper = helpers.permalink || (depth0 != null ? depth0.permalink : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"permalink","hash":{},"data":data}) : helper)))
+ + "\">\n <span class=\"icon icon-clippy\"></span>\n <span class=\"hidden-visually\">"
+ + alias4(((helper = (helper = helpers.permalinkTitle || (depth0 != null ? depth0.permalinkTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"permalinkTitle","hash":{},"data":data}) : helper)))
+ + "</span>\n </a>\n </div>\n <div class=\"file-details ellipsis\">\n"
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasFavoriteAction : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + " "
+ + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.hasSize : depth0),{"name":"if","hash":{},"fn":container.program(3, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "<span class=\"date live-relative-timestamp\" data-timestamp=\""
+ + alias4(((helper = (helper = helpers.timestamp || (depth0 != null ? depth0.timestamp : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"timestamp","hash":{},"data":data}) : helper)))
+ + "\" title=\""
+ + alias4(((helper = (helper = helpers.altDate || (depth0 != null ? depth0.altDate : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"altDate","hash":{},"data":data}) : helper)))
+ + "\">"
+ + alias4(((helper = (helper = helpers.date || (depth0 != null ? depth0.date : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"date","hash":{},"data":data}) : helper)))
+ + "</span>\n </div>\n</div>\n<div class=\"hidden permalink-field\">\n <input type=\"text\" value=\""
+ + alias4(((helper = (helper = helpers.permalink || (depth0 != null ? depth0.permalink : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"permalink","hash":{},"data":data}) : helper)))
+ + "\" placeholder=\""
+ + alias4(((helper = (helper = helpers.permalinkTitle || (depth0 != null ? depth0.permalinkTitle : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"permalinkTitle","hash":{},"data":data}) : helper)))
+ + "\" readonly=\"readonly\"/>\n</div>\n";
+},"useData":true});
+templates['newfilemenu'] = template({"1":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return " <li>\n <a href=\"#\" class=\"menuitem\" data-templatename=\""
+ + alias4(((helper = (helper = helpers.templateName || (depth0 != null ? depth0.templateName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"templateName","hash":{},"data":data}) : helper)))
+ + "\" data-filetype=\""
+ + alias4(((helper = (helper = helpers.fileType || (depth0 != null ? depth0.fileType : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileType","hash":{},"data":data}) : helper)))
+ + "\" data-action=\""
+ + alias4(((helper = (helper = helpers.id || (depth0 != null ? depth0.id : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"id","hash":{},"data":data}) : helper)))
+ + "\"><span class=\"icon "
+ + alias4(((helper = (helper = helpers.iconClass || (depth0 != null ? depth0.iconClass : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"iconClass","hash":{},"data":data}) : helper)))
+ + " svg\"></span><span class=\"displayname\">"
+ + alias4(((helper = (helper = helpers.displayName || (depth0 != null ? depth0.displayName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"displayName","hash":{},"data":data}) : helper)))
+ + "</span></a>\n </li>\n";
+},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var stack1, helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<ul>\n <li>\n <label for=\"file_upload_start\" class=\"menuitem\" data-action=\"upload\" title=\""
+ + alias4(((helper = (helper = helpers.uploadMaxHumanFilesize || (depth0 != null ? depth0.uploadMaxHumanFilesize : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"uploadMaxHumanFilesize","hash":{},"data":data}) : helper)))
+ + "\" tabindex=\"0\"><span class=\"svg icon icon-upload\"></span><span class=\"displayname\">"
+ + alias4(((helper = (helper = helpers.uploadLabel || (depth0 != null ? depth0.uploadLabel : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"uploadLabel","hash":{},"data":data}) : helper)))
+ + "</span></label>\n </li>\n"
+ + ((stack1 = helpers.each.call(alias1,(depth0 != null ? depth0.items : depth0),{"name":"each","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
+ + "</ul>\n";
+},"useData":true});
+templates['newfilemenu_filename_form'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<form class=\"filenameform\">\n <input id=\""
+ + alias4(((helper = (helper = helpers.cid || (depth0 != null ? depth0.cid : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"cid","hash":{},"data":data}) : helper)))
+ + "-input-"
+ + alias4(((helper = (helper = helpers.fileType || (depth0 != null ? depth0.fileType : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileType","hash":{},"data":data}) : helper)))
+ + "\" type=\"text\" value=\""
+ + alias4(((helper = (helper = helpers.fileName || (depth0 != null ? depth0.fileName : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"fileName","hash":{},"data":data}) : helper)))
+ + "\" autocomplete=\"off\" autocapitalize=\"off\">\n <input type=\"submit\" value=\" \" class=\"icon-confirm\" />\n</form>\n";
+},"useData":true});
+templates['template_addbutton'] = template({"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
+ var helper, alias1=depth0 != null ? depth0 : (container.nullContext || {}), alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
+
+ return "<a href=\"#\" class=\"button new\">\n <span class=\"icon "
+ + alias4(((helper = (helper = helpers.iconClass || (depth0 != null ? depth0.iconClass : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"iconClass","hash":{},"data":data}) : helper)))
+ + "\"></span>\n <span class=\"hidden-visually\">"
+ + alias4(((helper = (helper = helpers.addText || (depth0 != null ? depth0.addText : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"addText","hash":{},"data":data}) : helper)))
+ + "</span>\n</a>\n";
+},"useData":true});
+})(); \ No newline at end of file
diff --git a/apps/files/js/templates/detailsview.handlebars b/apps/files/js/templates/detailsview.handlebars
new file mode 100644
index 00000000000..841a8fe25fe
--- /dev/null
+++ b/apps/files/js/templates/detailsview.handlebars
@@ -0,0 +1,12 @@
+<div class="detailFileInfoContainer"></div>
+{{#if tabHeaders}}
+<ul class="tabHeaders">
+ {{#each tabHeaders}}
+ <li class="tabHeader" data-tabid="{{tabId}}" tabindex="0">
+ <a href="#" tabindex="-1">{{label}}</a>
+ </li>
+ {{/each}}
+</ul>
+{{/if}}
+<div class="tabsContainer"></div>
+<a class="close icon-close" href="#"><span class="hidden-visually">{{closeLabel}}</span></a>
diff --git a/apps/files/js/templates/detailsview.handlebars.js b/apps/files/js/templates/detailsview.handlebars.js
deleted file mode 100644
index c109da77a63..00000000000
--- a/apps/files/js/templates/detailsview.handlebars.js
+++ /dev/null
@@ -1,28 +0,0 @@
-(function() {
- var template = Handlebars.template, templates = OCA.Files.Templates = OCA.Files.Templates || {};
-templates['detailsview'] = template({"1":function(container,depth0,helpers,partials,data) {
- var stack1;
-
- return "<ul class=\"tabHeaders\">\n"
- + ((stack1 = helpers.each.call(depth0 != null ? depth0 : {},(depth0 != null ? depth0.tabHeaders : depth0),{"name":"each","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + "</ul>\n";
-},"2":function(container,depth0,helpers,partials,data) {
- var helper, alias1=depth0 != null ? depth0 : {}, alias2=helpers.helperMissing, alias3="function", alias4=container.escapeExpression;
-
- return " <li class=\"tabHeader\" data-tabid=\""
- + alias4(((helper = (helper = helpers.tabId || (depth0 != null ? depth0.tabId : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"tabId","hash":{},"data":data}) : helper)))
- + "\" data-tabindex=\""
- + alias4(((helper = (helper = helpers.tabIndex || (depth0 != null ? depth0.tabIndex : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"tabIndex","hash":{},"data":data}) : helper)))
- + "\">\n <a href=\"#\">"
- + alias4(((helper = (helper = helpers.label || (depth0 != null ? depth0.label : depth0)) != null ? helper : alias2),(typeof helper === alias3 ? helper.call(alias1,{"name":"label","hash":{},"data":data}) : helper)))
- + "</a>\n </li>\n";
-},"compiler":[7,">= 4.0.0"],"main":function(container,depth0,helpers,partials,data) {
- var stack1, helper, alias1=depth0 != null ? depth0 : {};
-
- return "<div class=\"detailFileInfoContainer\"></div>\n"
- + ((stack1 = helpers["if"].call(alias1,(depth0 != null ? depth0.tabHeaders : depth0),{"name":"if","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data})) != null ? stack1 : "")
- + "<div class=\"tabsContainer\">\n</div>\n<a class=\"close icon-close\" href=\"#\" alt=\""
- + container.escapeExpression(((helper = (helper = helpers.closeLabel || (depth0 != null ? depth0.closeLabel : depth0)) != null ? helper : helpers.helperMissing),(typeof helper === "function" ? helper.call(alias1,{"name":"closeLabel","hash":{},"data":data}) : helper)))
- + "\"></a>\n";
-},"useData":true});
-})();
diff --git a/apps/files/js/templates/favorite_mark.handlebars b/apps/files/js/templates/favorite_mark.handlebars
new file mode 100644
index 00000000000..7e0cb4385a8
--- /dev/null
+++ b/apps/files/js/templates/favorite_mark.handlebars
@@ -0,0 +1,4 @@
+<div class="favorite-mark {{#isFavorite}}permanent{{/isFavorite}}">
+ <span class="icon {{iconClass}}" />
+ <span class="hidden-visually">{{altText}}</span>
+</div>
diff --git a/apps/files/js/templates/file_action_trigger.handlebars b/apps/files/js/templates/file_action_trigger.handlebars
new file mode 100644
index 00000000000..d7112ee2b2f
--- /dev/null
+++ b/apps/files/js/templates/file_action_trigger.handlebars
@@ -0,0 +1,13 @@
+<a class="action action-{{nameLowerCase}}" href="#" data-action="{{name}}">
+ {{#if icon}}
+ <img class="svg" alt="{{altText}}" src="{{icon}}" />
+ {{else}}
+ {{#if iconClass}}
+ <span class="icon {{iconClass}}" />
+ {{/if}}
+ {{#unless hasDisplayName}}
+ <span class="hidden-visually">{{altText}}</span>
+ {{/unless}}
+ {{/if}}
+ {{#if displayName}}<span> {{displayName}}</span>{{/if}}
+</a>
diff --git a/apps/files/js/templates/filemultiselectmenu.handlebars b/apps/files/js/templates/filemultiselectmenu.handlebars
new file mode 100644
index 00000000000..9a723920db9
--- /dev/null
+++ b/apps/files/js/templates/filemultiselectmenu.handlebars
@@ -0,0 +1,14 @@
+<ul>
+ {{#each items}}
+ <li class="item-{{name}}">
+ <a href="#" class="menuitem action {{name}} permanent" data-action="{{name}}">
+ {{#if iconClass}}
+ <span class="icon {{iconClass}}"></span>
+ {{else}}
+ <span class="no-icon"></span>
+ {{/if}}
+ <span class="label">{{displayName}}</span>
+ </a>
+ </li>
+ {{/each}}
+</ul>
diff --git a/apps/files/js/templates/filesummary.handlebars b/apps/files/js/templates/filesummary.handlebars
new file mode 100644
index 00000000000..f975a2a7737
--- /dev/null
+++ b/apps/files/js/templates/filesummary.handlebars
@@ -0,0 +1,7 @@
+<span class="info">
+ <span class="dirinfo"></span>
+ <span class="connector">{{connectorLabel}}</span>
+ <span class="fileinfo"></span>
+ <span class="hiddeninfo"></span>
+ <span class="filter"></span>
+</span>
diff --git a/apps/files/js/templates/mainfileinfodetailsview.handlebars b/apps/files/js/templates/mainfileinfodetailsview.handlebars
new file mode 100644
index 00000000000..02a4cdb6416
--- /dev/null
+++ b/apps/files/js/templates/mainfileinfodetailsview.handlebars
@@ -0,0 +1,21 @@
+<div class="thumbnailContainer"><a href="#" class="thumbnail action-default"><div class="stretcher"/></a></div>
+<div class="file-details-container">
+ <div class="fileName">
+ <h3 title="{{name}}" class="ellipsis">{{name}}</h3>
+ <a class="permalink" href="{{permalink}}" title="{{permalinkTitle}}" data-clipboard-text="{{permalink}}">
+ <span class="icon icon-clippy"></span>
+ <span class="hidden-visually">{{permalinkTitle}}</span>
+ </a>
+ </div>
+ <div class="file-details ellipsis">
+ {{#if hasFavoriteAction}}
+ <a href="#" class="action action-favorite favorite permanent">
+ <span class="icon {{starClass}}" title="{{starAltText}}"></span>
+ </a>
+ {{/if}}
+ {{#if hasSize}}<span class="size" title="{{altSize}}">{{size}}</span>, {{/if}}<span class="date live-relative-timestamp" data-timestamp="{{timestamp}}" title="{{altDate}}">{{date}}</span>
+ </div>
+</div>
+<div class="hidden permalink-field">
+ <input type="text" value="{{permalink}}" placeholder="{{permalinkTitle}}" readonly="readonly"/>
+</div>
diff --git a/apps/files/js/templates/newfilemenu.handlebars b/apps/files/js/templates/newfilemenu.handlebars
new file mode 100644
index 00000000000..0d9ad9682ca
--- /dev/null
+++ b/apps/files/js/templates/newfilemenu.handlebars
@@ -0,0 +1,10 @@
+<ul>
+ <li>
+ <label for="file_upload_start" class="menuitem" data-action="upload" title="{{uploadMaxHumanFilesize}}" tabindex="0"><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>
diff --git a/apps/files/js/templates/newfilemenu_filename_form.handlebars b/apps/files/js/templates/newfilemenu_filename_form.handlebars
new file mode 100644
index 00000000000..5fc37ecf781
--- /dev/null
+++ b/apps/files/js/templates/newfilemenu_filename_form.handlebars
@@ -0,0 +1,4 @@
+<form class="filenameform">
+ <input id="{{cid}}-input-{{fileType}}" type="text" value="{{fileName}}" autocomplete="off" autocapitalize="off">
+ <input type="submit" value=" " class="icon-confirm" />
+</form>
diff --git a/apps/files/js/templates/template_addbutton.handlebars b/apps/files/js/templates/template_addbutton.handlebars
new file mode 100644
index 00000000000..62a022715a9
--- /dev/null
+++ b/apps/files/js/templates/template_addbutton.handlebars
@@ -0,0 +1,4 @@
+<a href="#" class="button new">
+ <span class="icon {{iconClass}}"></span>
+ <span class="hidden-visually">{{addText}}</span>
+</a>