mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-05-24 03:57:08 -04:00
Switch to ghu and eslint.
This commit is contained in:
parent
5d0770ca36
commit
0c6143704a
67 changed files with 192 additions and 307 deletions
42
src/_h5ai/public/js/lib/ext/autorefresh.js
Normal file
42
src/_h5ai/public/js/lib/ext/autorefresh.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
modulejs.define('ext/autorefresh', ['_', '$', 'core/event', 'core/location', 'core/settings'], function (_, $, event, location, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
interval: 5000
|
||||
}, allsettings.autorefresh);
|
||||
var timeoutId = null;
|
||||
|
||||
|
||||
function heartbeat() {
|
||||
|
||||
location.refresh();
|
||||
}
|
||||
|
||||
function before() {
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
|
||||
function after() {
|
||||
|
||||
clearTimeout(timeoutId);
|
||||
timeoutId = setTimeout(heartbeat, settings.interval);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings.interval = Math.max(1000, settings.interval);
|
||||
|
||||
event.sub('location.beforeChange', before);
|
||||
event.sub('location.beforeRefresh', before);
|
||||
event.sub('location.changed', after);
|
||||
event.sub('location.refreshed', after);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
175
src/_h5ai/public/js/lib/ext/contextmenu.js
Normal file
175
src/_h5ai/public/js/lib/ext/contextmenu.js
Normal file
|
@ -0,0 +1,175 @@
|
|||
modulejs.define('ext/contextmenu', ['_', '$', 'core/resource', 'core/settings'], function (_, $, resource, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false
|
||||
}, allsettings.contextmenu);
|
||||
var templateOverlay = '<div id="cm-overlay"/>';
|
||||
var templatePanel = '<div class="cm-panel"><ul/></div>';
|
||||
var templateSep = '<li class="cm-sep"/>';
|
||||
var templateEntry = '<li class="cm-entry"><span class="cm-icon"><img/></span><span class="cm-text"/></li>';
|
||||
var templateLabel = '<li class="cm-label"><span class="cm-text"/></li>';
|
||||
|
||||
|
||||
function createOverlay(callback) {
|
||||
|
||||
var $overlay = $(templateOverlay);
|
||||
|
||||
$overlay
|
||||
.on('click contextmenu', function (ev) {
|
||||
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
var cmId = $(ev.target).closest('.cm-entry').data('cm-id');
|
||||
|
||||
if (ev.target === $overlay[0] || cmId !== undefined) {
|
||||
$overlay.remove();
|
||||
callback(cmId);
|
||||
}
|
||||
});
|
||||
|
||||
return $overlay;
|
||||
}
|
||||
|
||||
function createPanel(menu) {
|
||||
|
||||
var $panel = $(templatePanel);
|
||||
var $ul = $panel.find('ul');
|
||||
var $li;
|
||||
|
||||
_.each(menu, function (entry) {
|
||||
|
||||
if (entry.type === '-') {
|
||||
$(templateSep).appendTo($ul);
|
||||
|
||||
} else if (entry.type === 'l') {
|
||||
$(templateLabel).appendTo($ul)
|
||||
.find('.cm-text').text(entry.text);
|
||||
|
||||
} else if (entry.type === 'e') {
|
||||
$li = $(templateEntry).appendTo($ul);
|
||||
$li.data('cm-id', entry.id);
|
||||
$li.find('.cm-text').text(entry.text);
|
||||
if (entry.icon) {
|
||||
$li.find('.cm-icon img').attr('src', resource.icon(entry.icon));
|
||||
} else {
|
||||
$li.find('.cm-icon').addClass('no-icon');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return $panel;
|
||||
}
|
||||
|
||||
function positionPanel($overlay, $panel, x, y) {
|
||||
|
||||
var margin = 4;
|
||||
|
||||
$panel.css({
|
||||
left: 0,
|
||||
top: 0,
|
||||
opacity: 0
|
||||
});
|
||||
$overlay.show();
|
||||
|
||||
var overlayOffset = $overlay.offset();
|
||||
var overlayLeft = overlayOffset.left;
|
||||
var overlayTop = overlayOffset.top;
|
||||
var overlayWidth = $overlay.outerWidth(true);
|
||||
var overlayHeight = $overlay.outerHeight(true);
|
||||
|
||||
// var panelOffset = $panel.offset();
|
||||
// var panelLeft = panelOffset.left;
|
||||
// var panelTop = panelOffset.top;
|
||||
var panelWidth = $panel.outerWidth(true);
|
||||
var panelHeight = $panel.outerHeight(true);
|
||||
|
||||
var posLeft = x;
|
||||
var posTop = y;
|
||||
|
||||
if (panelWidth > overlayWidth - 2 * margin) {
|
||||
posLeft = margin;
|
||||
panelWidth = overlayWidth - 2 * margin;
|
||||
}
|
||||
|
||||
if (panelHeight > overlayHeight - 2 * margin) {
|
||||
posTop = margin;
|
||||
panelHeight = overlayHeight - 2 * margin;
|
||||
}
|
||||
|
||||
if (posLeft < overlayLeft + margin) {
|
||||
posLeft = overlayLeft + margin;
|
||||
}
|
||||
|
||||
if (posLeft + panelWidth > overlayLeft + overlayWidth - margin) {
|
||||
posLeft = overlayLeft + overlayWidth - margin - panelWidth;
|
||||
}
|
||||
|
||||
if (posTop < overlayTop + margin) {
|
||||
posTop = overlayTop + margin;
|
||||
}
|
||||
|
||||
if (posTop + panelHeight > overlayTop + overlayHeight - margin) {
|
||||
posTop = overlayTop + overlayHeight - margin - panelHeight;
|
||||
}
|
||||
|
||||
$panel.css({
|
||||
left: posLeft,
|
||||
top: posTop,
|
||||
width: panelWidth,
|
||||
height: panelHeight,
|
||||
opacity: 1
|
||||
});
|
||||
}
|
||||
|
||||
function showMenuAt(x, y, menu, callback) {
|
||||
|
||||
var $overlay = createOverlay(callback);
|
||||
var $panel = createPanel(menu);
|
||||
$overlay.append($panel).appendTo('body');
|
||||
positionPanel($overlay, $panel, x, y);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
// settings.enabled = true;
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).on('contextmenu', function (ev) {
|
||||
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
$(ev.target).trigger($.Event('h5ai-contextmenu', {
|
||||
originalEvent: ev,
|
||||
showMenu: function (menu, callback) {
|
||||
|
||||
showMenuAt(ev.pageX, ev.pageY, menu, callback);
|
||||
}
|
||||
}));
|
||||
});
|
||||
|
||||
// var menu = [
|
||||
// {type: 'e', id: 'e1', text: 'testing context menus'},
|
||||
// {type: 'e', id: 'e2', text: 'another entry'},
|
||||
// {type: 'e', id: 'e3', text: 'one with icon', icon: 'folder'},
|
||||
// {type: '-'},
|
||||
// {type: 'e', id: 'e4', text: 'one with icon', icon: 'x'},
|
||||
// {type: 'e', id: 'e5', text: 'one with icon', icon: 'img'}
|
||||
// ];
|
||||
// var callback = function (res) {
|
||||
|
||||
// window.console.log('>> CB-RESULT >> ' + res);
|
||||
// };
|
||||
|
||||
// $(document).on('h5ai-contextmenu', '#items .item.folder', function (ev) {
|
||||
|
||||
// window.console.log('CM', ev);
|
||||
// ev.showMenu(menu, callback);
|
||||
// });
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
62
src/_h5ai/public/js/lib/ext/crumb.js
Normal file
62
src/_h5ai/public/js/lib/ext/crumb.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
modulejs.define('ext/crumb', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/settings', 'view/topbar'], function (_, $, event, location, resource, allsettings, topbar) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false
|
||||
}, allsettings.crumb);
|
||||
var crumbTemplate =
|
||||
'<a class="crumb">' +
|
||||
'<img class="sep" src="' + resource.image('crumb') + '" alt=">"/>' +
|
||||
'<span class="label"/>' +
|
||||
'</a>';
|
||||
var pageHintTemplate = '<img class="hint" src="' + resource.icon('folder-page') + '" alt="has index page"/>';
|
||||
var $crumbbar;
|
||||
|
||||
|
||||
function createHtml(item) {
|
||||
|
||||
var $html = $(crumbTemplate).data('item', item);
|
||||
item.$crumb = $html;
|
||||
location.setLink($html, item);
|
||||
|
||||
$html.find('.label').text(item.label);
|
||||
|
||||
if (item.isCurrentFolder()) {
|
||||
$html.addClass('active');
|
||||
}
|
||||
|
||||
if (!item.isManaged) {
|
||||
$html.append($(pageHintTemplate));
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function onLocationChanged(item) {
|
||||
|
||||
var $crumb = item.$crumb;
|
||||
|
||||
if ($crumb && $crumb.parent()[0] === $crumbbar[0]) {
|
||||
$crumbbar.children().removeClass('active');
|
||||
$crumb.addClass('active');
|
||||
} else {
|
||||
$crumbbar.empty();
|
||||
_.each(item.getCrumb(), function (item) {
|
||||
$crumbbar.append(createHtml(item));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$crumbbar = $('<div id="crumbbar"/>').appendTo(topbar.$flowbar);
|
||||
|
||||
event.sub('location.changed', onLocationChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
66
src/_h5ai/public/js/lib/ext/custom.js
Normal file
66
src/_h5ai/public/js/lib/ext/custom.js
Normal file
|
@ -0,0 +1,66 @@
|
|||
modulejs.define('ext/custom', ['_', '$', 'marked', 'core/event', 'core/server', 'core/settings'], function (_, $, marked, event, server, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false
|
||||
}, allsettings.custom);
|
||||
var $header;
|
||||
var $footer;
|
||||
var duration = 200;
|
||||
|
||||
|
||||
function onLocationChanged(item) {
|
||||
|
||||
server.request({action: 'get', custom: item.absHref}, function (response) {
|
||||
|
||||
var custom = response && response.custom;
|
||||
var hasHeader;
|
||||
var hasFooter;
|
||||
|
||||
if (custom) {
|
||||
var header = custom.header;
|
||||
var footer = custom.footer;
|
||||
var content;
|
||||
|
||||
if (header.content) {
|
||||
content = header.content;
|
||||
if (header.type === 'md') {
|
||||
content = marked(content);
|
||||
}
|
||||
$header.html(content).stop().slideDown(duration);
|
||||
hasHeader = true;
|
||||
}
|
||||
|
||||
if (footer.content) {
|
||||
content = footer.content;
|
||||
if (footer.type === 'md') {
|
||||
content = marked(content);
|
||||
}
|
||||
$footer.html(content).stop().slideDown(duration);
|
||||
hasFooter = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasHeader) {
|
||||
$header.stop().slideUp(duration);
|
||||
}
|
||||
if (!hasFooter) {
|
||||
$footer.stop().slideUp(duration);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$header = $('<div id="content-header"/>').hide().prependTo('#content');
|
||||
$footer = $('<div id="content-footer"/>').hide().appendTo('#content');
|
||||
|
||||
event.sub('location.changed', onLocationChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
76
src/_h5ai/public/js/lib/ext/download.js
Normal file
76
src/_h5ai/public/js/lib/ext/download.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
modulejs.define('ext/download', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/server', 'core/settings'], function (_, $, event, location, resource, server, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
type: 'php-tar',
|
||||
packageName: 'package',
|
||||
alwaysVisible: false
|
||||
}, allsettings.download);
|
||||
var template =
|
||||
'<div id="download" class="tool">' +
|
||||
'<img src="' + resource.image('download') + '" alt="download"/>' +
|
||||
'</div>';
|
||||
var selectedItems = [];
|
||||
var $download;
|
||||
|
||||
|
||||
function onSelection(items) {
|
||||
|
||||
selectedItems = items.slice(0);
|
||||
if (selectedItems.length) {
|
||||
$download.show();
|
||||
} else if (!settings.alwaysVisible) {
|
||||
$download.hide();
|
||||
}
|
||||
}
|
||||
|
||||
function onClick() {
|
||||
|
||||
var type = settings.type;
|
||||
var name = settings.packageName;
|
||||
var extension = (type === 'shell-zip') ? 'zip' : 'tar';
|
||||
|
||||
if (!name) {
|
||||
if (selectedItems.length === 1) {
|
||||
name = selectedItems[0].label;
|
||||
} else {
|
||||
name = location.getItem().label;
|
||||
}
|
||||
}
|
||||
|
||||
var query = {
|
||||
action: 'download',
|
||||
as: name + '.' + extension,
|
||||
type: type,
|
||||
baseHref: location.getAbsHref()
|
||||
};
|
||||
|
||||
_.each(selectedItems, function (item, idx) {
|
||||
|
||||
query['hrefs[' + idx + ']'] = item.absHref;
|
||||
});
|
||||
|
||||
server.formRequest(query);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$download = $(template)
|
||||
.hide()
|
||||
.appendTo('#toolbar')
|
||||
.on('click', onClick);
|
||||
|
||||
if (settings.alwaysVisible) {
|
||||
$download.show();
|
||||
}
|
||||
|
||||
event.sub('selection', onSelection);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
90
src/_h5ai/public/js/lib/ext/filter.js
Normal file
90
src/_h5ai/public/js/lib/ext/filter.js
Normal file
|
@ -0,0 +1,90 @@
|
|||
modulejs.define('ext/filter', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/settings', 'core/util', 'view/view'], function (_, $, event, location, resource, allsettings, util, view) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
advanced: false,
|
||||
debounceTime: 100
|
||||
}, allsettings.filter);
|
||||
var template =
|
||||
'<div id="filter" class="tool">' +
|
||||
'<img src="' + resource.image('filter') + '" alt="filter"/>' +
|
||||
'<input class="l10n_ph-filter" type="text" value=""/>' +
|
||||
'</div>';
|
||||
var inputIsVisible = false;
|
||||
var prevPattern = '';
|
||||
var $filter;
|
||||
var $input;
|
||||
|
||||
|
||||
function filter(pattern) {
|
||||
|
||||
pattern = pattern || '';
|
||||
if (pattern === prevPattern) {
|
||||
return;
|
||||
}
|
||||
prevPattern = pattern;
|
||||
|
||||
if (!pattern) {
|
||||
view.setLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
$filter.addClass('pending');
|
||||
|
||||
var re = new RegExp(pattern);
|
||||
var matchedItems = [];
|
||||
|
||||
_.each(location.getItem().content, function (item) {
|
||||
|
||||
if (re.test(item.label)) {
|
||||
matchedItems.push(item);
|
||||
}
|
||||
});
|
||||
|
||||
$filter.removeClass('pending');
|
||||
view.setHint('noMatch');
|
||||
view.setItems(matchedItems);
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
if (inputIsVisible) {
|
||||
$filter.addClass('active');
|
||||
$input.focus();
|
||||
filter(util.parsePattern($input.val(), settings.advanced));
|
||||
} else {
|
||||
filter();
|
||||
$filter.removeClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
|
||||
inputIsVisible = !inputIsVisible;
|
||||
update();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
||||
inputIsVisible = false;
|
||||
$input.val('');
|
||||
update();
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filter = $(template).appendTo('#toolbar');
|
||||
$input = $filter.find('input');
|
||||
|
||||
$filter.on('click', 'img', toggle);
|
||||
$input.on('keyup', _.debounce(update, settings.debounceTime, {trailing: true}));
|
||||
event.sub('location.changed', reset);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
49
src/_h5ai/public/js/lib/ext/google-analytics.js
Normal file
49
src/_h5ai/public/js/lib/ext/google-analytics.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
modulejs.define('ext/google-analytics-ua', ['_', 'core/event', 'core/settings'], function (_, event, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
id: 'UA-000000-0'
|
||||
}, allsettings['google-analytics-ua']);
|
||||
var win = window;
|
||||
var doc = document;
|
||||
var scriptLiteral = 'script';
|
||||
var id = 'h5ai-ga';
|
||||
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var el;
|
||||
var firstScriptElement;
|
||||
|
||||
win.GoogleAnalyticsObject = id;
|
||||
win[id] = win[id] || function () {
|
||||
(win[id].q = win[id].q || []).push(arguments);
|
||||
};
|
||||
win[id].l = 1 * new Date();
|
||||
|
||||
el = doc.createElement(scriptLiteral);
|
||||
el.async = true;
|
||||
el.src = '//www.google-analytics.com/analytics.js';
|
||||
|
||||
firstScriptElement = doc.getElementsByTagName(scriptLiteral)[0];
|
||||
firstScriptElement.parentNode.insertBefore(el, firstScriptElement);
|
||||
|
||||
win[id]('create', settings.id, 'auto');
|
||||
|
||||
event.sub('location.changed', function (item) {
|
||||
|
||||
var loc = win.location;
|
||||
win[id]('send', 'pageview', {
|
||||
location: loc.protocol + '//' + loc.host + item.absHref,
|
||||
title: _.pluck(item.getCrumb(), 'label').join(' > ')
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
162
src/_h5ai/public/js/lib/ext/info.js
Normal file
162
src/_h5ai/public/js/lib/ext/info.js
Normal file
|
@ -0,0 +1,162 @@
|
|||
modulejs.define('ext/info', ['_', '$', 'core/event', 'core/format', 'core/modernizr', 'core/resource', 'core/settings', 'core/store'], function (_, $, event, format, modernizr, resource, allsettings, store) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
show: false,
|
||||
qrcode: true,
|
||||
qrColor: '#999'
|
||||
}, allsettings.info);
|
||||
var template =
|
||||
'<div id="info">' +
|
||||
'<div class="icon"><img/></div>' +
|
||||
'<div class="block">' +
|
||||
'<div class="label"/>' +
|
||||
'<div class="time"/>' +
|
||||
'<div class="size"/>' +
|
||||
'<div class="content">' +
|
||||
'<span class="folders"/> <span class="l10n-folders"/>, ' +
|
||||
'<span class="files"/> <span class="l10n-files"/>' +
|
||||
'</div>' +
|
||||
'</div>' +
|
||||
'<div class="qrcode"/>' +
|
||||
'</div>';
|
||||
var settingsTemplate =
|
||||
'<div class="block">' +
|
||||
'<h1 class="l10n-info">Info</h1>' +
|
||||
'<div id="view-info" class="button view">' +
|
||||
'<img src="' + resource.image('info-toggle') + '" alt="view-info"/>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
var storekey = 'ext/info';
|
||||
var $img;
|
||||
var $label;
|
||||
var $time;
|
||||
var $size;
|
||||
var $content;
|
||||
var $folders;
|
||||
var $files;
|
||||
var $qrcode;
|
||||
var currentFolder;
|
||||
|
||||
|
||||
function updateSettings() {
|
||||
|
||||
if (store.get(storekey)) {
|
||||
$('#view-info').addClass('active');
|
||||
$('#info').show();
|
||||
} else {
|
||||
$('#view-info').removeClass('active');
|
||||
$('#info').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function update(item) {
|
||||
|
||||
var src = item.thumbRational || item.icon;
|
||||
var isThumb = Boolean(item.thumbRational);
|
||||
|
||||
if (item.isCurrentFolder() || !src) {
|
||||
src = resource.icon('folder');
|
||||
}
|
||||
|
||||
$img.attr('src', src);
|
||||
if (isThumb) {
|
||||
$img.addClass('thumb');
|
||||
} else {
|
||||
$img.removeClass('thumb');
|
||||
}
|
||||
|
||||
$label.text(item.label);
|
||||
if (_.isNumber(item.time)) {
|
||||
$time.text(format.formatDate(item.time));
|
||||
} else {
|
||||
$time.text('.');
|
||||
}
|
||||
|
||||
if (_.isNumber(item.size)) {
|
||||
$size.text(format.formatSize(item.size));
|
||||
$size.show();
|
||||
} else {
|
||||
$size.hide();
|
||||
}
|
||||
|
||||
if (item.isContentFetched) {
|
||||
var stats = item.getStats();
|
||||
$folders.text(stats.folders);
|
||||
$files.text(stats.files);
|
||||
$content.show();
|
||||
} else {
|
||||
$content.hide();
|
||||
}
|
||||
|
||||
if (settings.qrcode) {
|
||||
$qrcode.empty().qrcode({
|
||||
render: modernizr.canvas ? 'canvas' : 'div',
|
||||
size: 200,
|
||||
fill: settings.qrColor,
|
||||
background: null,
|
||||
text: window.location.protocol + '//' + window.location.host + item.absHref
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseenter(item) {
|
||||
|
||||
update(item);
|
||||
}
|
||||
|
||||
function onMouseleave() {
|
||||
|
||||
update(currentFolder);
|
||||
}
|
||||
|
||||
function onLocationChanged(item) {
|
||||
|
||||
currentFolder = item;
|
||||
update(currentFolder);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $info = $(template).appendTo('#mainrow');
|
||||
$img = $info.find('.icon img');
|
||||
$label = $info.find('.label');
|
||||
$time = $info.find('.time');
|
||||
$size = $info.find('.size');
|
||||
$content = $info.find('.content');
|
||||
$folders = $info.find('.folders');
|
||||
$files = $info.find('.files');
|
||||
$qrcode = $info.find('.qrcode');
|
||||
|
||||
if (!settings.qrcode) {
|
||||
$qrcode.remove();
|
||||
}
|
||||
|
||||
$(settingsTemplate)
|
||||
.appendTo('#sidebar')
|
||||
.find('#view-info')
|
||||
.on('click', function (ev) {
|
||||
|
||||
store.put(storekey, !store.get(storekey));
|
||||
updateSettings();
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
// ensure stored value is boolean, otherwise set default
|
||||
if (typeof (store.get(storekey)) !== 'boolean') {
|
||||
store.put(storekey, settings.show);
|
||||
}
|
||||
updateSettings();
|
||||
|
||||
event.sub('location.changed', onLocationChanged);
|
||||
event.sub('item.mouseenter', onMouseenter);
|
||||
event.sub('item.mouseleave', onMouseleave);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
141
src/_h5ai/public/js/lib/ext/l10n.js
Normal file
141
src/_h5ai/public/js/lib/ext/l10n.js
Normal file
|
@ -0,0 +1,141 @@
|
|||
modulejs.define('ext/l10n', ['_', '$', 'core/event', 'core/format', 'core/langs', 'core/server', 'core/settings', 'core/store'], function (_, $, event, format, langs, server, allsettings, store) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
lang: 'en',
|
||||
useBrowserLang: true
|
||||
}, allsettings.l10n);
|
||||
var defaultTranslations = {
|
||||
isoCode: 'en',
|
||||
lang: 'english',
|
||||
|
||||
dateFormat: 'YYYY-MM-DD HH:mm',
|
||||
details: 'details',
|
||||
download: 'download',
|
||||
empty: 'empty',
|
||||
files: 'files',
|
||||
filter: 'filter',
|
||||
folders: 'folders',
|
||||
grid: 'grid',
|
||||
icons: 'icons',
|
||||
language: 'Language',
|
||||
lastModified: 'Last modified',
|
||||
name: 'Name',
|
||||
noMatch: 'no match',
|
||||
parentDirectory: 'Parent Directory',
|
||||
search: 'search',
|
||||
size: 'Size',
|
||||
tree: 'Tree',
|
||||
view: 'View'
|
||||
};
|
||||
var blockTemplate = '<div class="block"><h1 class="l10n-language">Language</h1><div class="select"><select id="langs"/></div></div>';
|
||||
var optionTemplate = '<option/>';
|
||||
var storekey = 'ext/l10n';
|
||||
var loaded = {
|
||||
en: _.extend({}, defaultTranslations)
|
||||
};
|
||||
var currentLang = loaded.en;
|
||||
|
||||
|
||||
function update(lang) {
|
||||
|
||||
if (lang) {
|
||||
currentLang = lang;
|
||||
}
|
||||
|
||||
$('#langs option')
|
||||
.removeAttr('selected').removeProp('selected')
|
||||
.filter('.' + currentLang.isoCode)
|
||||
.attr('selected', 'selected').prop('selected', 'selected');
|
||||
|
||||
$.each(currentLang, function (key, value) {
|
||||
$('.l10n-' + key).text(value);
|
||||
$('.l10n_ph-' + key).attr('placeholder', value);
|
||||
});
|
||||
format.setDefaultDateFormat(currentLang.dateFormat);
|
||||
|
||||
$('#items .item .date').each(function () {
|
||||
|
||||
var $this = $(this);
|
||||
|
||||
$this.text(format.formatDate($this.data('time')));
|
||||
});
|
||||
}
|
||||
|
||||
function loadLanguage(isoCode, callback) {
|
||||
|
||||
if (loaded[isoCode]) {
|
||||
|
||||
callback(loaded[isoCode]);
|
||||
} else {
|
||||
|
||||
server.request({action: 'get', l10n: [isoCode]}, function (response) {
|
||||
|
||||
var json = response.l10n && response.l10n[isoCode] ? response.l10n[isoCode] : {};
|
||||
loaded[isoCode] = _.extend({}, defaultTranslations, json, {isoCode: isoCode});
|
||||
callback(loaded[isoCode]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function localize(langs, isoCode, useBrowserLang) {
|
||||
|
||||
var storedIsoCode = store.get(storekey);
|
||||
|
||||
if (langs[storedIsoCode]) {
|
||||
isoCode = storedIsoCode;
|
||||
} else if (useBrowserLang) {
|
||||
var browserLang = navigator.language || navigator.browserLanguage;
|
||||
if (browserLang) {
|
||||
if (langs[browserLang]) {
|
||||
isoCode = browserLang;
|
||||
} else if (browserLang.length > 2 && langs[browserLang.substr(0, 2)]) {
|
||||
isoCode = browserLang.substr(0, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!langs[isoCode]) {
|
||||
isoCode = 'en';
|
||||
}
|
||||
|
||||
loadLanguage(isoCode, update);
|
||||
}
|
||||
|
||||
function initLangSelector(langs) {
|
||||
|
||||
var isoCodes = _.keys(langs).sort();
|
||||
var $block = $(blockTemplate);
|
||||
var $select = $block.find('select')
|
||||
.on('change', function (event) {
|
||||
var isoCode = event.target.value;
|
||||
store.put(storekey, isoCode);
|
||||
localize(langs, isoCode, false);
|
||||
});
|
||||
|
||||
$.each(isoCodes, function (idx, isoCode) {
|
||||
$(optionTemplate)
|
||||
.attr('value', isoCode)
|
||||
.addClass(isoCode)
|
||||
.text(isoCode + ' - ' + (_.isString(langs[isoCode]) ? langs[isoCode] : langs[isoCode].lang))
|
||||
.appendTo($select);
|
||||
});
|
||||
|
||||
$block.appendTo('#sidebar');
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (settings.enabled) {
|
||||
initLangSelector(langs);
|
||||
}
|
||||
|
||||
event.sub('view.changed', function () {
|
||||
|
||||
localize(langs, settings.lang, settings.useBrowserLang);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
41
src/_h5ai/public/js/lib/ext/peer5.js
Normal file
41
src/_h5ai/public/js/lib/ext/peer5.js
Normal file
|
@ -0,0 +1,41 @@
|
|||
modulejs.define('ext/peer5', ['_', '$', 'core/settings'], function (_, $, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
id: 'z142i5n5qypq4cxr'
|
||||
}, allsettings.peer5);
|
||||
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var peer5js = '//api.peer5.com/peer5.js?id=' + settings.id;
|
||||
|
||||
// load peer5 with caching
|
||||
$.ajax({
|
||||
url: peer5js,
|
||||
dataType: 'script',
|
||||
cache: true
|
||||
});
|
||||
|
||||
// attach to file items, once the DOM is ready
|
||||
$(function () {
|
||||
|
||||
$('body').on('click', '.item.file > a', function (ev) {
|
||||
|
||||
if (window.peer5) {
|
||||
ev.preventDefault();
|
||||
var url = ev.currentTarget.href;
|
||||
window.peer5.download(url);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
32
src/_h5ai/public/js/lib/ext/piwik-analytics.js
Executable file
32
src/_h5ai/public/js/lib/ext/piwik-analytics.js
Executable file
|
@ -0,0 +1,32 @@
|
|||
modulejs.define('ext/piwik-analytics', ['_', '$', 'core/settings'], function (_, $, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
baseURL: 'not-set',
|
||||
idSite: 0
|
||||
}, allsettings['piwik-analytics']);
|
||||
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// reference: http://piwik.org/docs/javascript-tracking/
|
||||
|
||||
var pkBaseURL = ((document.location.protocol === 'https:') ? 'https://' : 'http://') + settings.baseURL + '/';
|
||||
|
||||
$('<script/>').attr('src', pkBaseURL + 'piwik.js').appendTo('body');
|
||||
$(window).load(function () {
|
||||
/*global Piwik */
|
||||
|
||||
var piwikTracker = Piwik.getTracker(pkBaseURL + 'piwik.php', settings.idSite);
|
||||
piwikTracker.trackPageView();
|
||||
piwikTracker.enableLinkTracking();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
117
src/_h5ai/public/js/lib/ext/preview-aud.js
Normal file
117
src/_h5ai/public/js/lib/ext/preview-aud.js
Normal file
|
@ -0,0 +1,117 @@
|
|||
modulejs.define('ext/preview-audio', ['_', '$', 'core/event', 'core/format', 'core/settings', 'ext/preview'], function (_, $, event, format, allsettings, preview) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
types: []
|
||||
}, allsettings['preview-aud']);
|
||||
|
||||
|
||||
function preloadAudio(src, callback) {
|
||||
|
||||
var $audio = $('<audio/>')
|
||||
.one('loadedmetadata', function () {
|
||||
|
||||
callback($audio);
|
||||
// setTimeout(function () { callback($img); }, 1000); // for testing
|
||||
})
|
||||
.attr('autoplay', 'autoplay')
|
||||
.attr('controls', 'controls')
|
||||
.attr('src', src);
|
||||
}
|
||||
|
||||
function onEnter(items, idx) {
|
||||
|
||||
var currentItems = items;
|
||||
var currentIdx = idx;
|
||||
var currentItem = items[idx];
|
||||
|
||||
function onAdjustSize() {
|
||||
|
||||
var $content = $('#pv-content');
|
||||
var $audio = $('#pv-aud-audio');
|
||||
|
||||
if ($audio.length) {
|
||||
|
||||
$audio.css({
|
||||
left: String(($content.width() - $audio.width()) * 0.5) + 'px',
|
||||
top: String(($content.height() - $audio.height()) * 0.5) + 'px'
|
||||
});
|
||||
|
||||
preview.setLabels([
|
||||
currentItem.label,
|
||||
format.formatDate($audio[0].duration * 1000, 'm:ss')
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function onIdxChange(rel) {
|
||||
|
||||
currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length;
|
||||
currentItem = currentItems[currentIdx];
|
||||
|
||||
var spinnerTimeout = setTimeout(function () { preview.showSpinner(true); }, 200);
|
||||
|
||||
if ($('#pv-aud-audio').length) {
|
||||
$('#pv-aud-audio')[0].pause();
|
||||
}
|
||||
preloadAudio(currentItem.absHref, function ($preloadedAudio) {
|
||||
|
||||
clearTimeout(spinnerTimeout);
|
||||
preview.showSpinner(false);
|
||||
|
||||
$('#pv-content').fadeOut(100, function () {
|
||||
|
||||
$('#pv-content').empty().append($preloadedAudio.attr('id', 'pv-aud-audio')).fadeIn(200);
|
||||
|
||||
// small timeout, so $preloadedAudio is visible and therefore $preloadedAudio.width is available
|
||||
setTimeout(function () {
|
||||
onAdjustSize();
|
||||
|
||||
preview.setIndex(currentIdx + 1, currentItems.length);
|
||||
preview.setRawLink(currentItem.absHref);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onIdxChange(0);
|
||||
preview.setOnIndexChange(onIdxChange);
|
||||
preview.setOnAdjustSize(onAdjustSize);
|
||||
preview.enter();
|
||||
}
|
||||
|
||||
function initItem(item) {
|
||||
|
||||
if (item.$view && _.indexOf(settings.types, item.type) >= 0) {
|
||||
item.$view.find('a').on('click', function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var matchedEntries = _.compact(_.map($('#items .item'), function (item) {
|
||||
|
||||
item = $(item).data('item');
|
||||
return _.indexOf(settings.types, item.type) >= 0 ? item : null;
|
||||
}));
|
||||
|
||||
onEnter(matchedEntries, _.indexOf(matchedEntries, item));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onViewChanged(added) {
|
||||
|
||||
_.each(added, initItem);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
154
src/_h5ai/public/js/lib/ext/preview-img.js
Normal file
154
src/_h5ai/public/js/lib/ext/preview-img.js
Normal file
|
@ -0,0 +1,154 @@
|
|||
modulejs.define('ext/preview-img', ['_', '$', 'core/event', 'core/server', 'core/settings', 'ext/preview'], function (_, $, event, server, allsettings, preview) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
size: null,
|
||||
types: []
|
||||
}, allsettings['preview-img']);
|
||||
var spinnerThreshold = 200;
|
||||
var spinnerTimeoutId;
|
||||
var currentItems;
|
||||
var currentIdx;
|
||||
var currentItem;
|
||||
|
||||
|
||||
function requestSample(href, callback) {
|
||||
|
||||
if (!settings.size) {
|
||||
callback(href);
|
||||
return;
|
||||
}
|
||||
|
||||
server.request({
|
||||
action: 'get',
|
||||
thumbs: [{
|
||||
type: 'img',
|
||||
href: href,
|
||||
width: settings.size,
|
||||
height: 0
|
||||
}]
|
||||
}, function (json) {
|
||||
|
||||
callback(json && json.thumbs && json.thumbs[0] ? json.thumbs[0] : null);
|
||||
});
|
||||
}
|
||||
|
||||
function preloadImage(item, callback) {
|
||||
|
||||
requestSample(item.absHref, function (src) {
|
||||
|
||||
$('<img/>')
|
||||
.one('load', function (ev) {
|
||||
|
||||
callback(item, ev.target);
|
||||
|
||||
// for testing
|
||||
// setTimeout(function () { callback(item, ev.target); }, 1000);
|
||||
})
|
||||
.attr('src', src);
|
||||
});
|
||||
}
|
||||
|
||||
function onAdjustSize() {
|
||||
|
||||
var $content = $('#pv-content');
|
||||
var $img = $('#pv-img-image');
|
||||
|
||||
if ($img.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$img.css({
|
||||
left: ($content.width() - $img.width()) * 0.5,
|
||||
top: ($content.height() - $img.height()) * 0.5
|
||||
});
|
||||
|
||||
var labels = [currentItem.label];
|
||||
if (!settings.size) {
|
||||
labels.push(String($img[0].naturalWidth) + 'x' + String($img[0].naturalHeight));
|
||||
labels.push(String((100 * $img.width() / $img[0].naturalWidth).toFixed(0)) + '%');
|
||||
}
|
||||
preview.setLabels(labels);
|
||||
}
|
||||
|
||||
function onIdxChange(rel) {
|
||||
|
||||
currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length;
|
||||
currentItem = currentItems[currentIdx];
|
||||
|
||||
preview.setLabels([currentItem.label]);
|
||||
preview.setIndex(currentIdx + 1, currentItems.length);
|
||||
preview.setRawLink(currentItem.absHref);
|
||||
|
||||
$('#pv-content').hide();
|
||||
if (preview.isSpinnerVisible()) {
|
||||
preview.showSpinner(true, currentItem.thumbSquare);
|
||||
} else {
|
||||
clearTimeout(spinnerTimeoutId);
|
||||
spinnerTimeoutId = setTimeout(function () {
|
||||
|
||||
preview.showSpinner(true, currentItem.thumbSquare);
|
||||
}, spinnerThreshold);
|
||||
}
|
||||
|
||||
preloadImage(currentItem, function (item, preloadedImage) {
|
||||
|
||||
if (item !== currentItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
clearTimeout(spinnerTimeoutId);
|
||||
preview.showSpinner(false);
|
||||
$('#pv-content')
|
||||
.empty()
|
||||
.append($(preloadedImage).attr('id', 'pv-img-image'))
|
||||
.show();
|
||||
onAdjustSize();
|
||||
});
|
||||
}
|
||||
|
||||
function onEnter(items, idx) {
|
||||
|
||||
currentItems = items;
|
||||
currentIdx = idx;
|
||||
preview.setOnIndexChange(onIdxChange);
|
||||
preview.setOnAdjustSize(onAdjustSize);
|
||||
preview.enter();
|
||||
onIdxChange(0);
|
||||
}
|
||||
|
||||
function initItem(item) {
|
||||
|
||||
if (item.$view && _.indexOf(settings.types, item.type) >= 0) {
|
||||
item.$view.find('a').on('click', function (ev) {
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
var matchedEntries = _.compact(_.map($('#items .item'), function (item) {
|
||||
|
||||
item = $(item).data('item');
|
||||
return _.indexOf(settings.types, item.type) >= 0 ? item : null;
|
||||
}));
|
||||
|
||||
onEnter(matchedEntries, _.indexOf(matchedEntries, item));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onViewChanged(added) {
|
||||
|
||||
_.each(added, initItem);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
151
src/_h5ai/public/js/lib/ext/preview-txt.js
Normal file
151
src/_h5ai/public/js/lib/ext/preview-txt.js
Normal file
|
@ -0,0 +1,151 @@
|
|||
modulejs.define('ext/preview-txt', ['_', '$', 'marked', 'prism', 'core/event', 'core/settings', 'ext/preview'], function (_, $, marked, prism, event, allsettings, preview) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
types: {}
|
||||
}, allsettings['preview-txt']);
|
||||
var tplText = '<pre id="pv-txt-text" class="highlighted"/>';
|
||||
var tplMarkdown = '<div id="pv-txt-text" class="markdown"/>';
|
||||
var spinnerThreshold = 200;
|
||||
var spinnerTimeoutId;
|
||||
var currentItems;
|
||||
var currentIdx;
|
||||
var currentItem;
|
||||
|
||||
|
||||
function preloadText(item, callback) {
|
||||
|
||||
$.ajax({
|
||||
url: item.absHref,
|
||||
dataType: 'text'
|
||||
})
|
||||
.done(function (content) {
|
||||
|
||||
callback(item, content);
|
||||
|
||||
// for testing
|
||||
// setTimeout(function () { callback(item, content); }, 1000);
|
||||
})
|
||||
.fail(function (jqXHR, textStatus) {
|
||||
|
||||
callback(item, '[ajax error] ' + textStatus);
|
||||
});
|
||||
}
|
||||
|
||||
function onAdjustSize() {
|
||||
|
||||
var $content = $('#pv-content');
|
||||
var $text = $('#pv-txt-text');
|
||||
|
||||
if ($text.length) {
|
||||
$text.height($content.height() - 16);
|
||||
}
|
||||
}
|
||||
|
||||
function onIdxChange(rel) {
|
||||
|
||||
currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length;
|
||||
currentItem = currentItems[currentIdx];
|
||||
|
||||
preview.setLabels([
|
||||
currentItem.label,
|
||||
String(currentItem.size) + ' bytes'
|
||||
]);
|
||||
preview.setIndex(currentIdx + 1, currentItems.length);
|
||||
preview.setRawLink(currentItem.absHref);
|
||||
|
||||
$('#pv-content').hide();
|
||||
if (preview.isSpinnerVisible()) {
|
||||
preview.showSpinner(true, currentItem.icon);
|
||||
} else {
|
||||
clearTimeout(spinnerTimeoutId);
|
||||
spinnerTimeoutId = setTimeout(function () {
|
||||
|
||||
preview.showSpinner(true, currentItem.icon);
|
||||
}, spinnerThreshold);
|
||||
}
|
||||
|
||||
preloadText(currentItem, function (item, textContent) {
|
||||
|
||||
if (item !== currentItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
var type = settings.types[currentItem.type];
|
||||
var $text;
|
||||
var $code;
|
||||
|
||||
if (type === 'none') {
|
||||
$text = $(tplMarkdown).text(textContent);
|
||||
} else if (type === 'fixed') {
|
||||
$text = $(tplText).text(textContent);
|
||||
} else if (type === 'markdown') {
|
||||
$text = $(tplMarkdown).html(marked(textContent));
|
||||
} else {
|
||||
$text = $(tplText);
|
||||
$code = $('<code/>').appendTo($text);
|
||||
|
||||
if (textContent.length < 20000) {
|
||||
$code.empty().html(prism.highlight(textContent, prism.languages[type]));
|
||||
} else {
|
||||
$code.empty().text(textContent);
|
||||
setTimeout(function () { $code.empty().html(prism.highlight(textContent, prism.languages[type])); }, 300);
|
||||
}
|
||||
}
|
||||
|
||||
clearTimeout(spinnerTimeoutId);
|
||||
preview.showSpinner(false);
|
||||
$('#pv-content')
|
||||
.empty()
|
||||
.append($text)
|
||||
.show();
|
||||
onAdjustSize();
|
||||
});
|
||||
}
|
||||
|
||||
function onEnter(items, idx) {
|
||||
|
||||
currentItems = items;
|
||||
currentIdx = idx;
|
||||
currentItem = items[idx];
|
||||
preview.setOnIndexChange(onIdxChange);
|
||||
preview.setOnAdjustSize(onAdjustSize);
|
||||
preview.enter();
|
||||
onIdxChange(0);
|
||||
}
|
||||
|
||||
function initItem(item) {
|
||||
|
||||
if (item.$view && _.indexOf(_.keys(settings.types), item.type) >= 0) {
|
||||
item.$view.find('a').on('click', function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var matchedEntries = _.compact(_.map($('#items .item'), function (item) {
|
||||
|
||||
item = $(item).data('item');
|
||||
return _.indexOf(_.keys(settings.types), item.type) >= 0 ? item : null;
|
||||
}));
|
||||
|
||||
onEnter(matchedEntries, _.indexOf(matchedEntries, item));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onViewChanged(added) {
|
||||
|
||||
_.each(added, initItem);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
118
src/_h5ai/public/js/lib/ext/preview-vid.js
Normal file
118
src/_h5ai/public/js/lib/ext/preview-vid.js
Normal file
|
@ -0,0 +1,118 @@
|
|||
modulejs.define('ext/preview-vid', ['_', '$', 'core/event', 'core/settings', 'ext/preview'], function (_, $, event, allsettings, preview) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
types: []
|
||||
}, allsettings['preview-vid']);
|
||||
|
||||
|
||||
function preloadVideo(src, callback) {
|
||||
|
||||
var $video = $('<video/>')
|
||||
.one('loadedmetadata', function () {
|
||||
|
||||
callback($video);
|
||||
// setTimeout(function () { callback($video); }, 1000); // for testing
|
||||
})
|
||||
.attr('autoplay', 'autoplay')
|
||||
.attr('controls', 'controls')
|
||||
.attr('src', src);
|
||||
}
|
||||
|
||||
function onEnter(items, idx) {
|
||||
|
||||
var currentItems = items;
|
||||
var currentIdx = idx;
|
||||
var currentItem = items[idx];
|
||||
|
||||
function onAdjustSize() {
|
||||
|
||||
var $content = $('#pv-content');
|
||||
var $vid = $('#pv-vid-video');
|
||||
|
||||
if ($vid.length) {
|
||||
|
||||
$vid.css({
|
||||
left: String(($content.width() - $vid.width()) * 0.5) + 'px',
|
||||
top: String(($content.height() - $vid.height()) * 0.5) + 'px'
|
||||
});
|
||||
|
||||
preview.setLabels([
|
||||
currentItem.label,
|
||||
String($vid[0].videoWidth) + 'x' + String($vid[0].videoHeight),
|
||||
String((100 * $vid.width() / $vid[0].videoWidth).toFixed(0)) + '%'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function onIdxChange(rel) {
|
||||
|
||||
currentIdx = (currentIdx + rel + currentItems.length) % currentItems.length;
|
||||
currentItem = currentItems[currentIdx];
|
||||
|
||||
var spinnerTimeout = setTimeout(function () { preview.showSpinner(true); }, 200);
|
||||
|
||||
if ($('#pv-vid-video').length) {
|
||||
$('#pv-vid-video')[0].pause();
|
||||
}
|
||||
preloadVideo(currentItem.absHref, function ($preloadedVideo) {
|
||||
|
||||
clearTimeout(spinnerTimeout);
|
||||
preview.showSpinner(false);
|
||||
|
||||
$('#pv-content').fadeOut(100, function () {
|
||||
|
||||
$('#pv-content').empty().append($preloadedVideo.attr('id', 'pv-vid-video')).fadeIn(200);
|
||||
|
||||
// small timeout, so $preloadedVideo is visible and therefore $preloadedVideo.width is available
|
||||
setTimeout(function () {
|
||||
onAdjustSize();
|
||||
|
||||
preview.setIndex(currentIdx + 1, currentItems.length);
|
||||
preview.setRawLink(currentItem.absHref);
|
||||
}, 10);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
onIdxChange(0);
|
||||
preview.setOnIndexChange(onIdxChange);
|
||||
preview.setOnAdjustSize(onAdjustSize);
|
||||
preview.enter();
|
||||
}
|
||||
|
||||
function initItem(item) {
|
||||
|
||||
if (item.$view && _.indexOf(settings.types, item.type) >= 0) {
|
||||
item.$view.find('a').on('click', function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
var matchedEntries = _.compact(_.map($('#items .item'), function (item) {
|
||||
|
||||
item = $(item).data('item');
|
||||
return _.indexOf(settings.types, item.type) >= 0 ? item : null;
|
||||
}));
|
||||
|
||||
onEnter(matchedEntries, _.indexOf(matchedEntries, item));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function onViewChanged(added) {
|
||||
|
||||
_.each(added, initItem);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
253
src/_h5ai/public/js/lib/ext/preview.js
Normal file
253
src/_h5ai/public/js/lib/ext/preview.js
Normal file
|
@ -0,0 +1,253 @@
|
|||
modulejs.define('ext/preview', ['_', '$', 'core/resource', 'core/settings', 'core/store'], function (_, $, resource, allsettings, store) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: true
|
||||
}, allsettings.preview);
|
||||
var $window = $(window);
|
||||
var tplOverlay =
|
||||
'<div id="pv-overlay">' +
|
||||
'<div id="pv-content"/>' +
|
||||
'<div id="pv-spinner"><img class="back"/><img class="spinner" src="' + resource.image('spinner') + '"/></div>' +
|
||||
'<div id="pv-prev-area" class="hof"><img src="' + resource.image('preview-prev') + '"/></div>' +
|
||||
'<div id="pv-next-area" class="hof"><img src="' + resource.image('preview-next') + '"/></div>' +
|
||||
'<div id="pv-bottombar" class="clearfix hof">' +
|
||||
'<ul id="pv-buttons">' +
|
||||
'<li id="pv-bar-close" class="bar-right bar-button"><img src="' + resource.image('preview-close') + '"/></li>' +
|
||||
'<li id="pv-bar-raw" class="bar-right"><a class="bar-button" target="_blank"><img src="' + resource.image('preview-raw') + '"/></a></li>' +
|
||||
'<li id="pv-bar-fullscreen" class="bar-right bar-button"><img src="' + resource.image('preview-fullscreen') + '"/></li>' +
|
||||
'<li id="pv-bar-next" class="bar-right bar-button"><img src="' + resource.image('preview-next') + '"/></li>' +
|
||||
'<li id="pv-bar-idx" class="bar-right bar-label"/>' +
|
||||
'<li id="pv-bar-prev" class="bar-right bar-button"><img src="' + resource.image('preview-prev') + '"/></li>' +
|
||||
'</ul>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
var storekey = 'ext/preview';
|
||||
var isFullscreen = store.get(storekey) || false;
|
||||
var userAliveTimeoutId = null;
|
||||
var onIndexChange = null;
|
||||
var onAdjustSize = null;
|
||||
var spinnerVisible = false;
|
||||
|
||||
|
||||
function adjustSize() {
|
||||
|
||||
var winWidth = $window.width();
|
||||
var winHeight = $window.height();
|
||||
var $container = $('#pv-content');
|
||||
var $spinner = $('#pv-spinner');
|
||||
var margin = isFullscreen ? 0 : 20;
|
||||
var barHeight = isFullscreen ? 0 : 48;
|
||||
|
||||
$container.css({
|
||||
width: winWidth - 2 * margin,
|
||||
height: winHeight - 2 * margin - barHeight,
|
||||
left: margin,
|
||||
top: margin
|
||||
});
|
||||
|
||||
$spinner.css({
|
||||
left: winWidth * 0.5,
|
||||
top: winHeight * 0.5
|
||||
});
|
||||
|
||||
if (isFullscreen) {
|
||||
$('#pv-overlay').addClass('fullscreen');
|
||||
$('#pv-bar-fullscreen').find('img').attr('src', resource.image('preview-no-fullscreen'));
|
||||
} else {
|
||||
$('#pv-overlay').removeClass('fullscreen');
|
||||
$('#pv-bar-fullscreen').find('img').attr('src', resource.image('preview-fullscreen'));
|
||||
}
|
||||
|
||||
if (_.isFunction(onAdjustSize)) {
|
||||
onAdjustSize(1);
|
||||
}
|
||||
}
|
||||
|
||||
function onEnter() {
|
||||
|
||||
setLabels([]);
|
||||
$('#pv-content').empty();
|
||||
$('#pv-overlay').stop(true, true).fadeIn(200);
|
||||
$window.on('keydown', onKeydown);
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
function onExit() {
|
||||
|
||||
$window.off('keydown', onKeydown);
|
||||
$('#pv-overlay').stop(true, true).fadeOut(200, function () {
|
||||
$('#pv-content').empty();
|
||||
setLabels([]);
|
||||
});
|
||||
}
|
||||
|
||||
function onNext() {
|
||||
|
||||
if (_.isFunction(onIndexChange)) {
|
||||
onIndexChange(1);
|
||||
}
|
||||
}
|
||||
|
||||
function onPrevious() {
|
||||
|
||||
if (_.isFunction(onIndexChange)) {
|
||||
onIndexChange(-1);
|
||||
}
|
||||
}
|
||||
|
||||
function userAlive() {
|
||||
|
||||
clearTimeout(userAliveTimeoutId);
|
||||
$('#pv-overlay .hof').stop(true, true).fadeIn(200);
|
||||
|
||||
if (isFullscreen) {
|
||||
userAliveTimeoutId = setTimeout(function () {
|
||||
|
||||
$('#pv-overlay .hof').stop(true, true).fadeOut(2000);
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
function onFullscreen() {
|
||||
|
||||
isFullscreen = !isFullscreen;
|
||||
store.put(storekey, isFullscreen);
|
||||
|
||||
userAlive();
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
function onKeydown(ev) {
|
||||
|
||||
var key = ev.which;
|
||||
|
||||
if (key === 27) { // esc
|
||||
ev.preventDefault();
|
||||
ev.stopImmediatePropagation();
|
||||
onExit();
|
||||
} else if (key === 8 || key === 37) { // backspace, left
|
||||
ev.preventDefault();
|
||||
ev.stopImmediatePropagation();
|
||||
onPrevious();
|
||||
} else if (key === 13 || key === 32 || key === 39) { // enter, space, right
|
||||
ev.preventDefault();
|
||||
ev.stopImmediatePropagation();
|
||||
onNext();
|
||||
} else if (key === 70) { // f
|
||||
ev.preventDefault();
|
||||
ev.stopImmediatePropagation();
|
||||
onFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
function setIndex(idx, total) {
|
||||
|
||||
if (_.isNumber(idx)) {
|
||||
$('#pv-bar-idx').text(String(idx) + (_.isNumber(total) ? '/' + String(total) : '')).show();
|
||||
} else {
|
||||
$('#pv-bar-idx').text('').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function setRawLink(href) {
|
||||
|
||||
if (href) {
|
||||
$('#pv-bar-raw').show().find('a').attr('href', href);
|
||||
} else {
|
||||
$('#pv-bar-raw').hide().find('a').attr('href', '#');
|
||||
}
|
||||
}
|
||||
|
||||
function setLabels(labels) {
|
||||
|
||||
$('#pv-buttons .bar-left').remove();
|
||||
_.each(labels, function (label) {
|
||||
|
||||
$('<li/>')
|
||||
.addClass('bar-left bar-label')
|
||||
.text(label)
|
||||
.appendTo('#pv-buttons');
|
||||
});
|
||||
}
|
||||
|
||||
function setOnIndexChange(fn) {
|
||||
|
||||
onIndexChange = fn;
|
||||
}
|
||||
|
||||
function setOnAdjustSize(fn) {
|
||||
|
||||
onAdjustSize = fn;
|
||||
}
|
||||
|
||||
function showSpinner(show, src, millis) {
|
||||
|
||||
if (!_.isNumber(millis)) {
|
||||
millis = 300;
|
||||
}
|
||||
|
||||
var $spinner = $('#pv-spinner').stop(true, true);
|
||||
var $back = $spinner.find('.back');
|
||||
|
||||
if (show) {
|
||||
if (src) {
|
||||
$back.attr('src', src).show();
|
||||
} else {
|
||||
$back.hide();
|
||||
}
|
||||
spinnerVisible = true;
|
||||
$spinner.fadeIn(millis);
|
||||
} else {
|
||||
spinnerVisible = false;
|
||||
$spinner.fadeOut(millis);
|
||||
}
|
||||
}
|
||||
|
||||
function isSpinnerVisible() {
|
||||
|
||||
return spinnerVisible;
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(tplOverlay).appendTo('body');
|
||||
|
||||
$('#pv-spinner').hide();
|
||||
$('#pv-bar-prev, #pv-prev-area').on('click', onPrevious);
|
||||
$('#pv-bar-next, #pv-next-area').on('click', onNext);
|
||||
$('#pv-bar-close').on('click', onExit);
|
||||
$('#pv-bar-fullscreen').on('click', onFullscreen);
|
||||
|
||||
$('#pv-overlay')
|
||||
.on('keydown', onKeydown)
|
||||
.on('mousemove mousedown', userAlive)
|
||||
.on('click mousedown mousemove keydown keypress', function (ev) {
|
||||
|
||||
if (ev.type === 'click' && (ev.target.id === 'pv-overlay' || ev.target.id === 'pv-content')) {
|
||||
onExit();
|
||||
}
|
||||
ev.stopImmediatePropagation();
|
||||
});
|
||||
|
||||
$window.on('resize load', adjustSize);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
|
||||
return {
|
||||
enter: onEnter,
|
||||
exit: onExit,
|
||||
setIndex: setIndex,
|
||||
setRawLink: setRawLink,
|
||||
setLabels: setLabels,
|
||||
setOnIndexChange: setOnIndexChange,
|
||||
setOnAdjustSize: setOnAdjustSize,
|
||||
showSpinner: showSpinner,
|
||||
isSpinnerVisible: isSpinnerVisible
|
||||
};
|
||||
});
|
92
src/_h5ai/public/js/lib/ext/search.js
Normal file
92
src/_h5ai/public/js/lib/ext/search.js
Normal file
|
@ -0,0 +1,92 @@
|
|||
modulejs.define('ext/search', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/server', 'core/settings', 'core/util', 'model/item', 'view/view'], function (_, $, event, location, resource, server, allsettings, util, Item, view) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
advanced: false,
|
||||
debounceTime: 300
|
||||
}, allsettings.search);
|
||||
var template =
|
||||
'<div id="search" class="tool">' +
|
||||
'<img src="' + resource.image('search') + '" alt="search"/>' +
|
||||
'<input class="l10n_ph-search" type="text" value=""/>' +
|
||||
'</div>';
|
||||
var inputIsVisible = false;
|
||||
var prevPattern = '';
|
||||
var $search;
|
||||
var $input;
|
||||
|
||||
|
||||
function search(pattern) {
|
||||
|
||||
pattern = pattern || '';
|
||||
if (pattern === prevPattern) {
|
||||
return;
|
||||
}
|
||||
prevPattern = pattern;
|
||||
|
||||
if (!pattern) {
|
||||
view.setLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
$search.addClass('pending');
|
||||
|
||||
server.request({
|
||||
action: 'get',
|
||||
search: {
|
||||
href: location.getAbsHref(),
|
||||
pattern: pattern
|
||||
}
|
||||
}, function (response) {
|
||||
|
||||
$search.removeClass('pending');
|
||||
view.setHint('noMatch');
|
||||
view.setItems(_.map(response.search, function (item) {
|
||||
|
||||
return Item.get(item);
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
if (inputIsVisible) {
|
||||
$search.addClass('active');
|
||||
$input.focus();
|
||||
search(util.parsePattern($input.val(), settings.advanced));
|
||||
} else {
|
||||
search();
|
||||
$search.removeClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
|
||||
inputIsVisible = !inputIsVisible;
|
||||
update();
|
||||
}
|
||||
|
||||
function reset() {
|
||||
|
||||
inputIsVisible = false;
|
||||
$input.val('');
|
||||
update();
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$search = $(template).appendTo('#toolbar');
|
||||
$input = $search.find('input');
|
||||
|
||||
$search.on('click', 'img', toggle);
|
||||
$input.on('keyup', _.debounce(update, settings.debounceTime, {trailing: true}));
|
||||
event.sub('location.changed', reset);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
209
src/_h5ai/public/js/lib/ext/select.js
Normal file
209
src/_h5ai/public/js/lib/ext/select.js
Normal file
|
@ -0,0 +1,209 @@
|
|||
modulejs.define('ext/select', ['_', '$', 'core/event', 'core/resource', 'core/settings'], function (_, $, event, resource, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
clickndrag: false,
|
||||
checkboxes: false
|
||||
}, allsettings.select);
|
||||
var template = '<span class="selector"><img src="' + resource.image('selected') + '" alt="selected"/></span>';
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
var l = 0;
|
||||
var t = 0;
|
||||
var w = 0;
|
||||
var h = 0;
|
||||
var isDragSelect;
|
||||
var isCtrlPressed;
|
||||
var shrink = 1 / 3;
|
||||
var $document = $(document);
|
||||
var $html = $('html');
|
||||
var $selectionRect = $('<div id="selection-rect"/>');
|
||||
|
||||
|
||||
function publish() {
|
||||
|
||||
var items = _.map($('#items .item.selected'), function (itemElement) {
|
||||
|
||||
return $(itemElement).data('item');
|
||||
});
|
||||
event.pub('selection', items);
|
||||
}
|
||||
|
||||
function elementRect($element) {
|
||||
|
||||
if (!$element.is(':visible')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var offset = $element.offset();
|
||||
var l = offset.left;
|
||||
var t = offset.top;
|
||||
var w = $element.outerWidth();
|
||||
var h = $element.outerHeight();
|
||||
return {l: l, t: t, w: w, h: h, r: l + w, b: t + h};
|
||||
}
|
||||
|
||||
function doOverlap(rect1, rect2) {
|
||||
|
||||
if (!rect1 || !rect2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var left = Math.max(rect1.l, rect2.l);
|
||||
var right = Math.min(rect1.r, rect2.r);
|
||||
var top = Math.max(rect1.t, rect2.t);
|
||||
var bottom = Math.min(rect1.b, rect2.b);
|
||||
var width = right - left;
|
||||
var height = bottom - top;
|
||||
|
||||
return (width >= 0 && height >= 0);
|
||||
}
|
||||
|
||||
function selectionUpdate(ev) {
|
||||
|
||||
l = Math.min(x, ev.pageX);
|
||||
t = Math.min(y, ev.pageY);
|
||||
w = Math.abs(x - ev.pageX);
|
||||
h = Math.abs(y - ev.pageY);
|
||||
|
||||
if (!isDragSelect && w < 4 && h < 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isDragSelect && !isCtrlPressed) {
|
||||
$('#items .item').removeClass('selected');
|
||||
publish();
|
||||
}
|
||||
|
||||
isDragSelect = true;
|
||||
$html.addClass('drag-select');
|
||||
|
||||
ev.preventDefault();
|
||||
$selectionRect
|
||||
.stop(true, true)
|
||||
.css({left: l, top: t, width: w, height: h, opacity: 1})
|
||||
.show();
|
||||
|
||||
var selRect = elementRect($selectionRect);
|
||||
$('#items .item').removeClass('selecting').each(function () {
|
||||
|
||||
var $item = $(this);
|
||||
var inter = doOverlap(selRect, elementRect($item.find('a')));
|
||||
|
||||
if (inter && !$item.hasClass('folder-parent')) {
|
||||
$item.addClass('selecting');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function selectionEnd(ev) {
|
||||
|
||||
$document.off('mousemove', selectionUpdate);
|
||||
|
||||
if (!isDragSelect) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
$('#items .item.selecting.selected').removeClass('selecting').removeClass('selected');
|
||||
$('#items .item.selecting').removeClass('selecting').addClass('selected');
|
||||
publish();
|
||||
|
||||
$html.removeClass('drag-select');
|
||||
$selectionRect
|
||||
.stop(true, true)
|
||||
.animate(
|
||||
{
|
||||
left: l + w * 0.5 * shrink,
|
||||
top: t + h * 0.5 * shrink,
|
||||
width: w * (1 - shrink),
|
||||
height: h * (1 - shrink),
|
||||
opacity: 0
|
||||
},
|
||||
300,
|
||||
function () {
|
||||
$selectionRect.hide();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function selectionStart(ev) {
|
||||
|
||||
// only on left button and don't block scrollbar
|
||||
if (ev.button !== 0 || ev.offsetX >= $('#content').width() - 14) {
|
||||
return;
|
||||
}
|
||||
|
||||
isDragSelect = false;
|
||||
isCtrlPressed = ev.ctrlKey || ev.metaKey;
|
||||
x = ev.pageX;
|
||||
y = ev.pageY;
|
||||
|
||||
$document
|
||||
.on('mousemove', selectionUpdate)
|
||||
.one('mouseup', selectionEnd);
|
||||
}
|
||||
|
||||
function onSelectorClick(ev) {
|
||||
|
||||
ev.stopImmediatePropagation();
|
||||
ev.preventDefault();
|
||||
|
||||
$(ev.target).closest('.item').toggleClass('selected');
|
||||
publish();
|
||||
}
|
||||
|
||||
function addCheckbox(item) {
|
||||
|
||||
if (item.$view && !item.isCurrentParentFolder()) {
|
||||
$(template)
|
||||
.on('click', onSelectorClick)
|
||||
.appendTo(item.$view.find('a'));
|
||||
}
|
||||
}
|
||||
|
||||
function onViewChanged(added, removed) {
|
||||
|
||||
if (settings.checkboxes) {
|
||||
_.each(added, addCheckbox);
|
||||
}
|
||||
|
||||
_.each(removed, function (item) {
|
||||
|
||||
if (item.$view) {
|
||||
item.$view.removeClass('selected');
|
||||
}
|
||||
});
|
||||
|
||||
publish();
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled || (!settings.clickndrag && !settings.checkboxes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
|
||||
if (settings.clickndrag) {
|
||||
$selectionRect.hide().appendTo('body');
|
||||
|
||||
$('#content')
|
||||
.on('mousedown', selectionStart)
|
||||
.on('drag dragstart', function (ev) {
|
||||
|
||||
ev.stopImmediatePropagation();
|
||||
ev.preventDefault();
|
||||
})
|
||||
.on('click', function () {
|
||||
|
||||
$('#items .item').removeClass('selected');
|
||||
publish();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
156
src/_h5ai/public/js/lib/ext/sort.js
Normal file
156
src/_h5ai/public/js/lib/ext/sort.js
Normal file
|
@ -0,0 +1,156 @@
|
|||
modulejs.define('ext/sort', ['_', '$', 'core/event', 'core/resource', 'core/settings', 'core/store', 'core/util'], function (_, $, event, resource, allsettings, store, util) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
column: 0,
|
||||
reverse: false,
|
||||
ignorecase: true,
|
||||
natural: false,
|
||||
folders: 0
|
||||
}, allsettings.sort);
|
||||
var storekey = 'ext/sort';
|
||||
var template = '<img src="' + resource.image('sort') + '" class="sort" alt="sort order" />';
|
||||
|
||||
|
||||
function getType(item) {
|
||||
|
||||
var $item = $(item);
|
||||
|
||||
if ($item.hasClass('folder-parent')) {
|
||||
return 0;
|
||||
}
|
||||
if ($item.hasClass('folder')) {
|
||||
if (settings.folders === 1) {
|
||||
return 2;
|
||||
} else if (settings.folders === 2) {
|
||||
return 3;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
function getName(item) {
|
||||
|
||||
return $(item).find('.label').text();
|
||||
}
|
||||
|
||||
function getTime(item) {
|
||||
|
||||
return $(item).find('.date').data('time');
|
||||
}
|
||||
|
||||
function getSize(item) {
|
||||
|
||||
return $(item).find('.size').data('bytes');
|
||||
}
|
||||
|
||||
|
||||
var columnGetters = {
|
||||
0: getName,
|
||||
1: getTime,
|
||||
2: getSize
|
||||
};
|
||||
var columnClasses = {
|
||||
0: 'label',
|
||||
1: 'date',
|
||||
2: 'size'
|
||||
};
|
||||
|
||||
|
||||
function cmpFn(getValue, reverse, ignorecase, natural) {
|
||||
|
||||
return function (item1, item2) {
|
||||
|
||||
var res;
|
||||
var val1;
|
||||
var val2;
|
||||
|
||||
res = getType(item1) - getType(item2);
|
||||
if (res !== 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
val1 = getValue(item1);
|
||||
val2 = getValue(item2);
|
||||
|
||||
if (isNaN(val1) || isNaN(val2)) {
|
||||
val1 = String(val1);
|
||||
val2 = String(val2);
|
||||
|
||||
if (ignorecase) {
|
||||
val1 = val1.toLowerCase();
|
||||
val2 = val2.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
res = natural ? util.naturalCmpFn(val1, val2) : util.regularCmpFn(val1, val2);
|
||||
return reverse ? -res : res;
|
||||
};
|
||||
}
|
||||
|
||||
function sortItems(column, reverse) {
|
||||
|
||||
var $headers = $('#items li.header a');
|
||||
var $header = $('#items li.header a.' + columnClasses[column]);
|
||||
var fn = cmpFn(columnGetters[column], reverse, settings.ignorecase, column === 0 && settings.natural);
|
||||
var $current = $('#items .item');
|
||||
var $sorted = $('#items .item').sort(fn);
|
||||
|
||||
store.put(storekey, {column: column, reverse: reverse});
|
||||
|
||||
$headers.removeClass('ascending descending');
|
||||
$header.addClass(reverse ? 'descending' : 'ascending');
|
||||
|
||||
for (var i = 0, l = $current.length; i < l; i += 1) {
|
||||
if ($current[i] !== $sorted[i]) {
|
||||
$sorted.detach().sort(fn).appendTo('#items');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onContentChanged() {
|
||||
|
||||
var order = store.get(storekey);
|
||||
var column = order && order.column || settings.column;
|
||||
var reverse = order && order.reverse || settings.reverse;
|
||||
|
||||
sortItems(column, reverse);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $header = $('#items li.header');
|
||||
|
||||
$header.find('a.label')
|
||||
.append(template)
|
||||
.click(function (ev) {
|
||||
sortItems(0, $(this).hasClass('ascending'));
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
$header.find('a.date')
|
||||
.prepend(template)
|
||||
.click(function (ev) {
|
||||
sortItems(1, $(this).hasClass('ascending'));
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
$header.find('a.size')
|
||||
.prepend(template)
|
||||
.click(function (ev) {
|
||||
sortItems(2, $(this).hasClass('ascending'));
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
event.sub('view.changed', onContentChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
121
src/_h5ai/public/js/lib/ext/thumbnails.js
Normal file
121
src/_h5ai/public/js/lib/ext/thumbnails.js
Normal file
|
@ -0,0 +1,121 @@
|
|||
modulejs.define('ext/thumbnails', ['_', 'core/event', 'core/server', 'core/settings'], function (_, event, server, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
img: ['img-bmp', 'img-gif', 'img-ico', 'img-jpg', 'img-png'],
|
||||
mov: ['vid-avi', 'vid-flv', 'vid-mkv', 'vid-mov', 'vid-mp4', 'vid-mpg', 'vid-webm'],
|
||||
doc: ['x-pdf', 'x-ps'],
|
||||
delay: 1,
|
||||
size: 100,
|
||||
exif: false
|
||||
}, allsettings.thumbnails);
|
||||
var landscapeRatio = 4 / 3;
|
||||
|
||||
|
||||
function queueItem(queue, item) {
|
||||
|
||||
var type = null;
|
||||
|
||||
if (_.contains(settings.img, item.type)) {
|
||||
type = 'img';
|
||||
} else if (_.contains(settings.mov, item.type)) {
|
||||
type = 'mov';
|
||||
} else if (_.contains(settings.doc, item.type)) {
|
||||
type = 'doc';
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.thumbSquare) {
|
||||
item.$view.find('.icon.square img').addClass('thumb').attr('src', item.thumbSquare);
|
||||
} else {
|
||||
queue.push({
|
||||
type: type,
|
||||
href: item.absHref,
|
||||
ratio: 1,
|
||||
callback: function (src) {
|
||||
|
||||
if (src && item.$view) {
|
||||
item.thumbSquare = src;
|
||||
item.$view.find('.icon.square img').addClass('thumb').attr('src', src);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (item.thumbRational) {
|
||||
item.$view.find('.icon.landscape img').addClass('thumb').attr('src', item.thumbRational);
|
||||
} else {
|
||||
queue.push({
|
||||
type: type,
|
||||
href: item.absHref,
|
||||
ratio: landscapeRatio,
|
||||
callback: function (src) {
|
||||
|
||||
if (src && item.$view) {
|
||||
item.thumbRational = src;
|
||||
item.$view.find('.icon.landscape img').addClass('thumb').attr('src', src);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function requestQueue(queue) {
|
||||
|
||||
var thumbs = _.map(queue, function (req) {
|
||||
|
||||
return {
|
||||
type: req.type,
|
||||
href: req.href,
|
||||
width: Math.round(settings.size * req.ratio),
|
||||
height: settings.size
|
||||
};
|
||||
});
|
||||
|
||||
server.request({
|
||||
action: 'get',
|
||||
thumbs: thumbs
|
||||
}, function (json) {
|
||||
|
||||
_.each(queue, function (req, idx) {
|
||||
|
||||
req.callback(json && json.thumbs ? json.thumbs[idx] : null);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function handleItems(items) {
|
||||
|
||||
var queue = [];
|
||||
|
||||
_.each(items, function (item) {
|
||||
|
||||
queueItem(queue, item);
|
||||
});
|
||||
|
||||
if (queue.length) {
|
||||
requestQueue(queue);
|
||||
}
|
||||
}
|
||||
|
||||
function onViewChanged(added) {
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
handleItems(added);
|
||||
}, settings.delay);
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('view.changed', onViewChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
29
src/_h5ai/public/js/lib/ext/title.js
Normal file
29
src/_h5ai/public/js/lib/ext/title.js
Normal file
|
@ -0,0 +1,29 @@
|
|||
modulejs.define('ext/title', ['_', 'core/event', 'core/settings'], function (_, event, allsettings) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false
|
||||
}, allsettings.title);
|
||||
|
||||
function onLocationChanged(item) {
|
||||
|
||||
var labels = _.pluck(item.getCrumb(), 'label');
|
||||
var title = labels.join(' > ');
|
||||
|
||||
if (labels.length > 1) {
|
||||
title = labels[labels.length - 1] + ' - ' + title;
|
||||
}
|
||||
|
||||
document.title = title;
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.sub('location.changed', onLocationChanged);
|
||||
}
|
||||
|
||||
init();
|
||||
});
|
222
src/_h5ai/public/js/lib/ext/tree.js
Normal file
222
src/_h5ai/public/js/lib/ext/tree.js
Normal file
|
@ -0,0 +1,222 @@
|
|||
modulejs.define('ext/tree', ['_', '$', 'core/event', 'core/location', 'core/resource', 'core/settings', 'core/store', 'core/util'], function (_, $, event, location, resource, allsettings, store, util) {
|
||||
|
||||
var settings = _.extend({
|
||||
enabled: false,
|
||||
show: true,
|
||||
maxSubfolders: 50,
|
||||
naturalSort: false,
|
||||
ignorecase: true
|
||||
}, allsettings.tree);
|
||||
var template =
|
||||
'<div class="item">' +
|
||||
'<span class="indicator none">' +
|
||||
'<img src="' + resource.image('tree-indicator') + '"/>' +
|
||||
'</span>' +
|
||||
'<a>' +
|
||||
'<span class="icon"><img/></span>' +
|
||||
'<span class="label"/>' +
|
||||
'</a>' +
|
||||
'</span>';
|
||||
var settingsTemplate =
|
||||
'<div class="block">' +
|
||||
'<h1 class="l10n-tree">Tree</h1>' +
|
||||
'<div id="view-tree" class="button view">' +
|
||||
'<img src="' + resource.image('tree-toggle') + '" alt="view-tree"/>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
var storekey = 'ext/tree';
|
||||
|
||||
|
||||
function cmpFn(item1, item2) {
|
||||
|
||||
var val1 = item1.label;
|
||||
var val2 = item2.label;
|
||||
|
||||
if (settings.ignorecase) {
|
||||
val1 = val1.toLowerCase();
|
||||
val2 = val2.toLowerCase();
|
||||
}
|
||||
|
||||
return settings.natural ? util.naturalCmpFn(val1, val2) : util.regularCmpFn(val1, val2);
|
||||
}
|
||||
|
||||
function update(item) {
|
||||
|
||||
var $html = $(template);
|
||||
var $indicator = $html.find('.indicator');
|
||||
var $a = $html.find('a');
|
||||
var $img = $html.find('.icon img');
|
||||
var $label = $html.find('.label');
|
||||
|
||||
$html
|
||||
.addClass(item.isFolder() ? 'folder' : 'file')
|
||||
.data('item', item);
|
||||
|
||||
location.setLink($a, item);
|
||||
$img.attr('src', resource.icon('folder'));
|
||||
$label.text(item.label);
|
||||
|
||||
if (item.isFolder()) {
|
||||
|
||||
var subfolders = item.getSubfolders();
|
||||
|
||||
// indicator
|
||||
if ((item.isManaged && !item.isContentFetched) || subfolders.length) {
|
||||
|
||||
$indicator.removeClass('none');
|
||||
|
||||
if ((item.isManaged && !item.isContentFetched)) {
|
||||
$indicator.addClass('unknown');
|
||||
} else if (item.isContentVisible) {
|
||||
$indicator.addClass('open');
|
||||
} else {
|
||||
$indicator.addClass('close');
|
||||
}
|
||||
}
|
||||
|
||||
// is it the current folder?
|
||||
if (item.isCurrentFolder()) {
|
||||
$html.addClass('active');
|
||||
}
|
||||
|
||||
// does it have subfolders?
|
||||
if (subfolders.length) {
|
||||
subfolders.sort(cmpFn);
|
||||
|
||||
var $ul = $('<ul class="content"/>').appendTo($html);
|
||||
var counter = 0;
|
||||
_.each(subfolders, function (e) {
|
||||
counter += 1;
|
||||
if (counter <= settings.maxSubfolders) {
|
||||
$('<li/>').append(update(e)).appendTo($ul);
|
||||
}
|
||||
});
|
||||
if (subfolders.length > settings.maxSubfolders) {
|
||||
$('<li class="summary">… ' + (subfolders.length - settings.maxSubfolders) + ' more subfolders</li>').appendTo($ul);
|
||||
}
|
||||
if (!item.isContentVisible) {
|
||||
$ul.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// reflect folder status
|
||||
if (!item.isManaged) {
|
||||
$img.attr('src', resource.icon('folder-page'));
|
||||
}
|
||||
}
|
||||
|
||||
if (item.$tree) {
|
||||
item.$tree.replaceWith($html);
|
||||
}
|
||||
item.$tree = $html;
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
function createOnIndicatorClick() {
|
||||
|
||||
function slide(item, $indicator, $content, down) {
|
||||
|
||||
item.isContentVisible = down;
|
||||
$indicator.removeClass('open close').addClass(down ? 'open' : 'close');
|
||||
$content[down ? 'slideDown' : 'slideUp']();
|
||||
}
|
||||
|
||||
return function () {
|
||||
|
||||
var $indicator = $(this);
|
||||
var $item = $indicator.closest('.item');
|
||||
var item = $item.data('item');
|
||||
var $content = $item.find('> ul.content');
|
||||
|
||||
if ($indicator.hasClass('unknown')) {
|
||||
|
||||
item.fetchContent(function (item) {
|
||||
|
||||
item.isContentVisible = false;
|
||||
|
||||
var $item = update(item);
|
||||
var $indicator = $item.find('> .indicator');
|
||||
var $content = $item.find('> ul.content');
|
||||
|
||||
if (!$indicator.hasClass('none')) {
|
||||
slide(item, $indicator, $content, true);
|
||||
}
|
||||
});
|
||||
|
||||
} else if ($indicator.hasClass('open')) {
|
||||
|
||||
slide(item, $indicator, $content, false);
|
||||
|
||||
} else if ($indicator.hasClass('close')) {
|
||||
|
||||
slide(item, $indicator, $content, true);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function fetchTree(item, callback) {
|
||||
|
||||
item.isContentVisible = true;
|
||||
item.fetchContent(function (item) {
|
||||
|
||||
if (item.parent) {
|
||||
fetchTree(item.parent, callback);
|
||||
} else {
|
||||
callback(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateSettings() {
|
||||
|
||||
if (store.get(storekey)) {
|
||||
$('#view-tree').addClass('active');
|
||||
$('#tree').show();
|
||||
} else {
|
||||
$('#view-tree').removeClass('active');
|
||||
$('#tree').hide();
|
||||
}
|
||||
}
|
||||
|
||||
function onLocationChanged(item) {
|
||||
|
||||
fetchTree(item, function (root) {
|
||||
|
||||
$('#tree').append(update(root));
|
||||
updateSettings();
|
||||
});
|
||||
}
|
||||
|
||||
function init() {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('<div id="tree"/>')
|
||||
.appendTo('#mainrow')
|
||||
.on('click', '.indicator', createOnIndicatorClick());
|
||||
|
||||
$(settingsTemplate)
|
||||
.appendTo('#sidebar')
|
||||
.find('#view-tree')
|
||||
.on('click', function (ev) {
|
||||
|
||||
store.put(storekey, !store.get(storekey));
|
||||
updateSettings();
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
// ensure stored value is boolean, otherwise set default
|
||||
if (typeof (store.get(storekey)) !== 'boolean') {
|
||||
store.put(storekey, settings.show);
|
||||
}
|
||||
updateSettings();
|
||||
|
||||
event.sub('location.changed', onLocationChanged);
|
||||
}
|
||||
|
||||
|
||||
init();
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue