diff --git a/src/_h5ai/client/js/inc/view/content.js b/src/_h5ai/client/js/inc/view/content.js
index cc78c89d..8c2a1c69 100644
--- a/src/_h5ai/client/js/inc/view/content.js
+++ b/src/_h5ai/client/js/inc/view/content.js
@@ -1,160 +1,8 @@
-modulejs.define('view/content', ['_', '$', 'core/event', 'core/format', 'core/location', 'core/resource', 'core/settings', 'view/mainrow'], function (_, $, event, format, location, resource, allsettings, mainrow) {
+modulejs.define('view/content', ['$', 'view/mainrow'], function ($, mainrow) {
- var settings = _.extend({
- binaryPrefix: false,
- hideFolders: false,
- hideParentFolder: false,
- setParentFolderLabels: false
- }, allsettings.view);
- var itemTemplate =
- '
' +
- '' +
- '
' +
- '
' +
- '' +
- '' +
- '' +
- '' +
- '';
- var contentTemplate =
- '';
- var $content = $(contentTemplate);
- var $view = $content.find('#view');
- var $items = $view.find('#items');
- var $empty = $view.find('.empty');
-
-
- function update(item) {
-
- var $html = $(itemTemplate);
- var $a = $html.find('a');
- var $iconImg = $html.find('.icon img');
- var $label = $html.find('.label');
- var $date = $html.find('.date');
- var $size = $html.find('.size');
-
- $html
- .addClass(item.isFolder() ? 'folder' : 'file')
- .data('item', item);
-
- location.setLink($a, item);
-
- $label.text(item.label).attr('title', item.label);
- $date.data('time', item.time).text(format.formatDate(item.time));
- $size.data('bytes', item.size).text(format.formatSize(item.size));
- item.icon = resource.icon(item.type);
-
- if (item.isFolder() && !item.isManaged) {
- $html.addClass('page');
- item.icon = resource.icon('folder-page');
- }
-
- if (item.isCurrentParentFolder()) {
- item.icon = resource.icon('folder-parent');
- if (!settings.setParentFolderLabels) {
- $label.addClass('l10n-parentDirectory');
- }
- $html.addClass('folder-parent');
- }
- $iconImg.attr('src', item.icon).attr('alt', item.type);
-
- item.$view = $html;
-
- return $html;
- }
-
- function onMouseenter() {
-
- var item = $(this).closest('.item').data('item');
- event.pub('item.mouseenter', item);
- }
-
- function onMouseleave() {
-
- var item = $(this).closest('.item').data('item');
- event.pub('item.mouseleave', item);
- }
-
- function onLocationChanged(item) {
-
- $items.find('.item').remove();
-
- if (item.parent && !settings.hideParentFolder) {
- $items.append(update(item.parent));
- }
-
- _.each(item.content, function (e) {
-
- if (!(e.isFolder() && settings.hideFolders)) {
- $items.append(update(e));
- }
- });
-
- if (item.isEmpty()) {
- $empty.show();
- } else {
- $empty.hide();
- }
-
- $content.scrollLeft(0).scrollTop(0);
- }
-
- function onLocationRefreshed(item, added, removed) {
-
- _.each(added, function (item) {
-
- if (!(item.isFolder() && settings.hideFolders)) {
- update(item).hide().appendTo($items).fadeIn(400);
- }
- });
-
- _.each(removed, function (item) {
-
- item.$view.fadeOut(400, function () {
- item.$view.remove();
- });
- });
-
- if (item.isEmpty()) {
- setTimeout(function () { $empty.show(); }, 400);
- } else {
- $empty.hide();
- }
- }
-
- function init() {
-
- $content.appendTo(mainrow.$el);
- $empty.hide();
-
- format.setDefaultMetric(settings.binaryPrefix);
-
- $items
- .on('mouseenter', '.item a', onMouseenter)
- .on('mouseleave', '.item a', onMouseleave);
-
- event.sub('location.changed', onLocationChanged);
- event.sub('location.refreshed', onLocationRefreshed);
- }
-
-
- init();
+ var $content = $('').appendTo(mainrow.$el);
return {
- $el: $content,
- $view: $view,
- $items: $items
+ $el: $content
};
});
diff --git a/src/_h5ai/client/js/inc/view/item.js b/src/_h5ai/client/js/inc/view/item.js
new file mode 100644
index 00000000..ed42ec4f
--- /dev/null
+++ b/src/_h5ai/client/js/inc/view/item.js
@@ -0,0 +1,60 @@
+modulejs.define('view/item', ['_', '$', 'core/format', 'core/location', 'core/resource', 'core/settings'], function (_, $, format, location, resource, allsettings) {
+
+ var settings = _.extend({
+ setParentFolderLabels: false
+ }, allsettings.view);
+ var template =
+ '' +
+ '' +
+ '
' +
+ '
' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '';
+
+
+ function renderItem(item) {
+
+ var $html = $(template);
+ var $a = $html.find('a');
+ var $iconImg = $html.find('.icon img');
+ var $label = $html.find('.label');
+ var $date = $html.find('.date');
+ var $size = $html.find('.size');
+
+ $html
+ .addClass(item.isFolder() ? 'folder' : 'file')
+ .data('item', item);
+
+ location.setLink($a, item);
+
+ $label.text(item.label).attr('title', item.label);
+ $date.data('time', item.time).text(format.formatDate(item.time));
+ $size.data('bytes', item.size).text(format.formatSize(item.size));
+ item.icon = resource.icon(item.type);
+
+ if (item.isFolder() && !item.isManaged) {
+ $html.addClass('page');
+ item.icon = resource.icon('folder-page');
+ }
+
+ if (item.isCurrentParentFolder()) {
+ item.icon = resource.icon('folder-parent');
+ if (!settings.setParentFolderLabels) {
+ $label.addClass('l10n-parentDirectory');
+ }
+ $html.addClass('folder-parent');
+ }
+ $iconImg.attr('src', item.icon).attr('alt', item.type);
+
+ item.$view = $html;
+
+ return $html;
+ }
+
+ return {
+ render: renderItem
+ };
+});
diff --git a/src/_h5ai/client/js/inc/view/view.js b/src/_h5ai/client/js/inc/view/view.js
new file mode 100644
index 00000000..9a0fa82c
--- /dev/null
+++ b/src/_h5ai/client/js/inc/view/view.js
@@ -0,0 +1,106 @@
+modulejs.define('view/view', ['_', '$', 'core/event', 'core/format', 'core/settings', 'view/content', 'view/item'], function (_, $, event, format, allsettings, content, viewitem) {
+
+ var settings = _.extend({
+ binaryPrefix: false,
+ hideFolders: false,
+ hideParentFolder: false
+ }, allsettings.view);
+ var template =
+ '';
+ var $view = $(template);
+ var $items = $view.find('#items');
+ var $empty = $view.find('.empty');
+
+
+ function onMouseenter() {
+
+ var item = $(this).closest('.item').data('item');
+ event.pub('item.mouseenter', item);
+ }
+
+ function onMouseleave() {
+
+ var item = $(this).closest('.item').data('item');
+ event.pub('item.mouseleave', item);
+ }
+
+ function onLocationChanged(item) {
+
+ $items.find('.item').remove();
+
+ if (item.parent && !settings.hideParentFolder) {
+ $items.append(viewitem.render(item.parent));
+ }
+
+ _.each(item.content, function (e) {
+
+ if (!(e.isFolder() && settings.hideFolders)) {
+ $items.append(viewitem.render(e));
+ }
+ });
+
+ if (item.isEmpty()) {
+ $empty.show();
+ } else {
+ $empty.hide();
+ }
+
+ content.$el.scrollLeft(0).scrollTop(0);
+ }
+
+ function onLocationRefreshed(item, added, removed) {
+
+ _.each(added, function (item) {
+
+ if (!(item.isFolder() && settings.hideFolders)) {
+ viewitem.render(item).hide().appendTo($items).fadeIn(400);
+ }
+ });
+
+ _.each(removed, function (item) {
+
+ item.$view.fadeOut(400, function () {
+ item.$view.remove();
+ });
+ });
+
+ if (item.isEmpty()) {
+ setTimeout(function () { $empty.show(); }, 400);
+ } else {
+ $empty.hide();
+ }
+ }
+
+ function init() {
+
+ $view.appendTo(content.$el);
+ $empty.hide();
+
+ format.setDefaultMetric(settings.binaryPrefix);
+
+ $items
+ .on('mouseenter', '.item a', onMouseenter)
+ .on('mouseleave', '.item a', onMouseleave);
+
+ event.sub('location.changed', onLocationChanged);
+ event.sub('location.refreshed', onLocationRefreshed);
+ }
+
+
+ init();
+
+ return {
+ $el: $view,
+ $items: $items
+ };
+});
diff --git a/src/_h5ai/client/js/inc/view/viewmode.js b/src/_h5ai/client/js/inc/view/viewmode.js
index b70570df..588b5cdf 100644
--- a/src/_h5ai/client/js/inc/view/viewmode.js
+++ b/src/_h5ai/client/js/inc/view/viewmode.js
@@ -1,4 +1,4 @@
-modulejs.define('view/viewmode', ['_', '$', 'core/resource', 'core/settings', 'core/store', 'view/content', 'view/sidebar'], function (_, $, resource, allsettings, store, content, sidebar) {
+modulejs.define('view/viewmode', ['_', '$', 'core/resource', 'core/settings', 'core/store', 'view/sidebar', 'view/view'], function (_, $, resource, allsettings, store, sidebar, view) {
var modes = ['details', 'grid', 'icons'];
var settings = _.extend({}, {
@@ -66,23 +66,23 @@ modulejs.define('view/viewmode', ['_', '$', 'core/resource', 'core/settings', 'c
_.each(modes, function (m) {
if (m === mode) {
$('#view-' + m).addClass('active');
- content.$view.addClass('view-' + m);
+ view.$el.addClass('view-' + m);
} else {
$('#view-' + m).removeClass('active');
- content.$view.removeClass('view-' + m);
+ view.$el.removeClass('view-' + m);
}
});
_.each(sortedSizes, function (s) {
if (s === size) {
- content.$view.addClass('view-size-' + s);
+ view.$el.addClass('view-size-' + s);
} else {
- content.$view.removeClass('view-size-' + s);
+ view.$el.removeClass('view-size-' + s);
}
});
$('#view-size').val(_.indexOf(sortedSizes, size));
- content.$view.show();
+ view.$el.show();
}
function addViewSettings() {
diff --git a/test/tests/unit/view/content.js b/test/tests/unit/view/content.js
index 43cc58b4..9c23e34c 100644
--- a/test/tests/unit/view/content.js
+++ b/test/tests/unit/view/content.js
@@ -2,7 +2,7 @@
'use strict';
var ID = 'view/content';
-var DEPS = ['_', '$', 'core/event', 'core/format', 'core/location', 'core/resource', 'core/settings', 'view/mainrow'];
+var DEPS = ['$', 'view/mainrow'];
describe('module \'' + ID + '\'', function () {
@@ -10,35 +10,10 @@ describe('module \'' + ID + '\'', function () {
this.definition = modulejs._private.definitions[ID];
- this.xSettings = util.uniqObj();
- this.xResource = {
- icon: sinon.stub().returns(util.uniqPath('-icon.png'))
- };
- this.xFormat = {
- formatSize: sinon.stub().returns(util.uniqId()),
- formatDate: sinon.stub().returns(util.uniqId()),
- setDefaultMetric: sinon.stub()
- };
- this.xEvent = {
- sub: sinon.stub(),
- pub: sinon.stub()
- };
- this.xLocation = {
- setLink: sinon.stub()
- };
this.xMainrow = {$el: null};
-
this.applyFn = function () {
- this.xResource.icon.reset();
- this.xFormat.formatSize.reset();
- this.xFormat.formatDate.reset();
- this.xFormat.setDefaultMetric.reset();
- this.xEvent.sub.reset();
- this.xEvent.pub.reset();
- this.xLocation.setLink.reset();
-
- return this.definition.fn(_, $, this.xEvent, this.xFormat, this.xLocation, this.xResource, this.xSettings, this.xMainrow);
+ return this.definition.fn($, this.xMainrow);
};
});
@@ -88,11 +63,11 @@ describe('module \'' + ID + '\'', function () {
describe('application', function () {
- it('returns object with 3 properties', function () {
+ it('returns object with 1 property', function () {
var instance = this.applyFn();
assert.isPlainObject(instance);
- assert.lengthOfKeys(instance, 3);
+ assert.lengthOfKeys(instance, 1);
});
it('adds HTML #content to #mainrow', function () {
@@ -100,44 +75,6 @@ describe('module \'' + ID + '\'', function () {
this.applyFn();
assert.lengthOf($('#mainrow > #content'), 1);
});
-
- it('adds HTML #view to #content', function () {
-
- this.applyFn();
- assert.lengthOf($('#content > #view'), 1);
- });
-
- it('adds HTML #items to #view', function () {
-
- this.applyFn();
- assert.lengthOf($('#view > #items'), 1);
- });
-
- it('sets default metric', function () {
-
- this.applyFn();
- assert.isTrue(this.xFormat.setDefaultMetric.calledOnce);
- });
-
- it('subscribes to 2 events', function () {
-
- this.applyFn();
- assert.isTrue(this.xEvent.sub.calledTwice);
- });
-
- it('subscribes to location.changed', function () {
-
- this.applyFn();
- assert.strictEqual(this.xEvent.sub.firstCall.args[0], 'location.changed');
- assert.isFunction(this.xEvent.sub.firstCall.args[1]);
- });
-
- it('subscribes to location.refreshed', function () {
-
- this.applyFn();
- assert.strictEqual(this.xEvent.sub.secondCall.args[0], 'location.refreshed');
- assert.isFunction(this.xEvent.sub.secondCall.args[1]);
- });
});
describe('.$el', function () {
@@ -151,30 +88,6 @@ describe('module \'' + ID + '\'', function () {
assert.strictEqual(instance.$el.attr('id'), 'content');
});
});
-
- describe('.$view', function () {
-
- it('is $(\'#view\')', function () {
-
- var instance = this.applyFn();
- assert.isObject(instance.$view);
- assert.lengthOf(instance.$view, 1);
- assert.isString(instance.$view.jquery);
- assert.strictEqual(instance.$view.attr('id'), 'view');
- });
- });
-
- describe('.$items', function () {
-
- it('is $(\'#items\')', function () {
-
- var instance = this.applyFn();
- assert.isObject(instance.$items);
- assert.lengthOf(instance.$items, 1);
- assert.isString(instance.$items.jquery);
- assert.strictEqual(instance.$items.attr('id'), 'items');
- });
- });
});
}());
diff --git a/test/tests/unit/view/view.js b/test/tests/unit/view/view.js
new file mode 100644
index 00000000..0058a9e9
--- /dev/null
+++ b/test/tests/unit/view/view.js
@@ -0,0 +1,152 @@
+(function () {
+'use strict';
+
+var ID = 'view/view';
+var DEPS = ['_', '$', 'core/event', 'core/format', 'core/settings', 'view/content', 'view/item'];
+
+describe('module \'' + ID + '\'', function () {
+
+ before(function () {
+
+ this.definition = modulejs._private.definitions[ID];
+
+ this.xEvent = {
+ sub: sinon.stub(),
+ pub: sinon.stub()
+ };
+ this.xFormat = {
+ setDefaultMetric: sinon.stub()
+ };
+ this.xSettings = util.uniqObj();
+ this.xContent = {$el: null};
+ this.xItem = {render: sinon.stub()};
+
+ this.applyFn = function () {
+
+ this.xEvent.sub.reset();
+ this.xEvent.pub.reset();
+ this.xFormat.setDefaultMetric.reset();
+ this.xItem.render.reset();
+
+ return this.definition.fn(_, $, this.xEvent, this.xFormat, this.xSettings, this.xContent, this.xItem);
+ };
+ });
+
+ after(function () {
+
+ util.restoreHtml();
+ });
+
+ beforeEach(function () {
+
+ util.restoreHtml();
+ this.xContent.$el = $('').appendTo('body');
+ });
+
+ describe('definition', function () {
+
+ it('is defined', function () {
+
+ assert.isPlainObject(this.definition);
+ });
+
+ it('has correct id', function () {
+
+ assert.strictEqual(this.definition.id, ID);
+ });
+
+ it('requires correct', function () {
+
+ assert.deepEqual(this.definition.deps, DEPS);
+ });
+
+ it('args for each request', function () {
+
+ assert.strictEqual(this.definition.deps.length, this.definition.fn.length);
+ });
+
+ it('has no instance', function () {
+
+ assert.notProperty(modulejs._private.instances, ID);
+ });
+
+ it('inits without errors', function () {
+
+ this.applyFn();
+ });
+ });
+
+ describe('application', function () {
+
+ it('returns object with 2 properties', function () {
+
+ var instance = this.applyFn();
+ assert.isPlainObject(instance);
+ assert.lengthOfKeys(instance, 2);
+ });
+
+ it('adds HTML #view to #content', function () {
+
+ this.applyFn();
+ assert.lengthOf($('#content > #view'), 1);
+ });
+
+ it('adds HTML #items to #view', function () {
+
+ this.applyFn();
+ assert.lengthOf($('#view > #items'), 1);
+ });
+
+ it('sets default metric', function () {
+
+ this.applyFn();
+ assert.isTrue(this.xFormat.setDefaultMetric.calledOnce);
+ });
+
+ it('subscribes to 2 events', function () {
+
+ this.applyFn();
+ assert.isTrue(this.xEvent.sub.calledTwice);
+ });
+
+ it('subscribes to location.changed', function () {
+
+ this.applyFn();
+ assert.strictEqual(this.xEvent.sub.firstCall.args[0], 'location.changed');
+ assert.isFunction(this.xEvent.sub.firstCall.args[1]);
+ });
+
+ it('subscribes to location.refreshed', function () {
+
+ this.applyFn();
+ assert.strictEqual(this.xEvent.sub.secondCall.args[0], 'location.refreshed');
+ assert.isFunction(this.xEvent.sub.secondCall.args[1]);
+ });
+ });
+
+ describe('.$el', function () {
+
+ it('is $(\'#view\')', function () {
+
+ var instance = this.applyFn();
+ assert.isObject(instance.$el);
+ assert.lengthOf(instance.$el, 1);
+ assert.isString(instance.$el.jquery);
+ assert.strictEqual(instance.$el.attr('id'), 'view');
+ });
+ });
+
+ describe('.$items', function () {
+
+ it('is $(\'#items\')', function () {
+
+ var instance = this.applyFn();
+ assert.isObject(instance.$items);
+ assert.lengthOf(instance.$items, 1);
+ assert.isString(instance.$items.jquery);
+ assert.strictEqual(instance.$items.attr('id'), 'items');
+ });
+ });
+});
+
+}());
diff --git a/test/tests/unit/view/viewmode.js b/test/tests/unit/view/viewmode.js
index f915e5b7..5324b328 100644
--- a/test/tests/unit/view/viewmode.js
+++ b/test/tests/unit/view/viewmode.js
@@ -2,7 +2,7 @@
'use strict';
var ID = 'view/viewmode';
-var DEPS = ['_', '$', 'core/resource', 'core/settings', 'core/store', 'view/content', 'view/sidebar'];
+var DEPS = ['_', '$', 'core/resource', 'core/settings', 'core/store', 'view/sidebar', 'view/view'];
describe('module \'' + ID + '\'', function () {
@@ -10,18 +10,18 @@ describe('module \'' + ID + '\'', function () {
this.definition = modulejs._private.definitions[ID];
- this.xSettings = {
- view: {}
- };
this.xResource = {
image: sinon.stub().returns(util.uniqPath('-image.png'))
};
+ this.xSettings = {
+ view: {}
+ };
this.xStore = {
get: sinon.stub(),
put: sinon.stub()
};
- this.xContent = {$view: null};
this.xSidebar = {$el: null};
+ this.xView = {$el: null};
this.applyFn = function () {
@@ -29,7 +29,7 @@ describe('module \'' + ID + '\'', function () {
this.xStore.get.reset();
this.xStore.put.reset();
- return this.definition.fn(_, $, this.xResource, this.xSettings, this.xStore, this.xContent, this.xSidebar);
+ return this.definition.fn(_, $, this.xResource, this.xSettings, this.xStore, this.xSidebar, this.xView);
};
});
@@ -41,8 +41,8 @@ describe('module \'' + ID + '\'', function () {
beforeEach(function () {
util.restoreHtml();
- this.xContent.$view = $('').appendTo('body');
this.xSidebar.$el = $('').appendTo('body');
+ this.xView.$el = $('').appendTo('body');
});
describe('definition', function () {