mirror of
https://github.com/lrsjng/h5ai.git
synced 2025-05-25 20:44:53 -04:00
Refactored and lots of modification. See README.md.
This commit is contained in:
parent
859a680e19
commit
71ed41fa69
85 changed files with 3191 additions and 2969 deletions
|
@ -1,373 +0,0 @@
|
|||
|
||||
Module.define('conhtml', [jQuery, 'settings', 'path', 'util', 'core', 'localize'], function ($, settings, pathFactory, util, core, localize) {
|
||||
|
||||
var cache = {},
|
||||
pathnameStatusCache = {},
|
||||
contentTypeRegEx = /^text\/html;h5ai=/,
|
||||
getPath = function (folder, tableRow) {
|
||||
|
||||
var absHref = util.getAbsHref(folder, tableRow),
|
||||
path = cache[absHref];
|
||||
|
||||
if (!path) {
|
||||
path = pathFactory.create(folder, tableRow);
|
||||
if (!path.isParentFolder) {
|
||||
cache[path.absHref] = path;
|
||||
}
|
||||
}
|
||||
|
||||
return path;
|
||||
},
|
||||
fetchStatus = function (pathname, callback) {
|
||||
|
||||
if (settings.folderStatus[pathname]) {
|
||||
callback(settings.folderStatus[pathname]);
|
||||
return;
|
||||
} else if (pathnameStatusCache[pathname]) {
|
||||
callback(pathnameStatusCache[pathname]);
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: pathname,
|
||||
type: 'HEAD',
|
||||
complete: function (xhr) {
|
||||
|
||||
var status = xhr.status;
|
||||
|
||||
if (status === 200 && contentTypeRegEx.test(xhr.getResponseHeader('Content-Type'))) {
|
||||
status = 'h5ai';
|
||||
}
|
||||
pathnameStatusCache[pathname] = status;
|
||||
callback(status);
|
||||
}
|
||||
});
|
||||
},
|
||||
updatePath = function (path) {
|
||||
|
||||
if (path.isFolder && !path.isParentFolder && path.status === undefined) {
|
||||
fetchStatus(path.absHref, function (status) {
|
||||
|
||||
if (status !== 'h5ai') {
|
||||
path.status = status;
|
||||
}
|
||||
updateHtml(path);
|
||||
core.linkHoverStates();
|
||||
});
|
||||
}
|
||||
},
|
||||
updatePaths = function () {
|
||||
|
||||
$.each(cache, function (ref, cached) {
|
||||
updatePath(cached);
|
||||
});
|
||||
},
|
||||
fetchStatusAndContent = function (pathname, includeParent, callback) {
|
||||
|
||||
fetchStatus(pathname, function (status) {
|
||||
|
||||
if (status !== 'h5ai') {
|
||||
callback(status, {});
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: pathname,
|
||||
type: 'GET',
|
||||
dataType: 'html',
|
||||
error: function (xhr) {
|
||||
|
||||
callback(xhr.status, {}); // since it was checked before this should never happen
|
||||
},
|
||||
success: function (html, status, xhr) {
|
||||
|
||||
var content = {};
|
||||
|
||||
if (!contentTypeRegEx.test(xhr.getResponseHeader('Content-Type'))) {
|
||||
callback(xhr.status, {}); // since it was checked before this should never happen
|
||||
return;
|
||||
}
|
||||
|
||||
$(html).find('#table td').closest('tr').each(function () {
|
||||
|
||||
var path = getPath(pathname, this);
|
||||
|
||||
if (path.isFolder && (!path.isParentFolder || includeParent)) {
|
||||
content[path.absHref] = path;
|
||||
updatePath(path);
|
||||
}
|
||||
});
|
||||
callback('h5ai', content);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
var onClick = function (path, context) {
|
||||
|
||||
},
|
||||
updateCrumbHtml = function (path) {
|
||||
|
||||
var $html, $a;
|
||||
|
||||
if (path.html.$crumb && path.html.$crumb.data("status") === path.status) {
|
||||
return path.html.$crumb;
|
||||
}
|
||||
|
||||
$html = $("<li class='crumb'><a><img alt='>' /><span></span></a></li>")
|
||||
.addClass(path.isFolder ? "folder" : "file");
|
||||
|
||||
if (path.status) {
|
||||
$html.data("status", path.status);
|
||||
}
|
||||
|
||||
$a = $html.find("a")
|
||||
.attr("href", path.absHref)
|
||||
.click(function() { onClick(path, "crumb"); })
|
||||
.find("img").attr("src", core.image("crumb")).end()
|
||||
.find("span").text(path.label).end();
|
||||
|
||||
if (path.isDomain) {
|
||||
$html.addClass("domain");
|
||||
$a.find("img").attr("src", core.image("home"));
|
||||
}
|
||||
|
||||
if (path.isCurrentFolder) {
|
||||
$html.addClass("current");
|
||||
}
|
||||
|
||||
if (!isNaN(path.status)) {
|
||||
if (path.status === 200) {
|
||||
$a.append($("<img class='hint' src='" + core.image("page") + "' alt='not listable' />"));
|
||||
} else {
|
||||
$a.append($("<span class='hint'>(" + path.status + ")</span>"));
|
||||
}
|
||||
}
|
||||
|
||||
if (path.html.$crumb) {
|
||||
path.html.$crumb.replaceWith($html);
|
||||
}
|
||||
path.html.$crumb = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
updateExtendedHtml = function (path) {
|
||||
|
||||
var $html, $a, $label,
|
||||
imgClass = "",
|
||||
icon16 = core.icon(path.type),
|
||||
icon48 = core.icon(path.type, true);
|
||||
|
||||
if (path.html.$extended && path.html.$extended.data("status") === path.status) {
|
||||
return path.html.$extended;
|
||||
}
|
||||
|
||||
$html = $("<li class='entry' />")
|
||||
.data("path", path)
|
||||
.addClass(path.isFolder ? "folder" : "file");
|
||||
|
||||
if (path.status) {
|
||||
$html.data("status", path.status);
|
||||
}
|
||||
|
||||
if (settings.showThumbs === true && $.inArray(path.type, settings.thumbTypes) >= 0) {
|
||||
imgClass = "class='thumb'";
|
||||
var escapedHref = path.absHref.replace(/'/g, "%27").replace(/"/g, "%22");
|
||||
icon16 = core.api() + "?action=thumb&href=" + escapedHref + "&width=16&height=16&mode=square";
|
||||
icon48 = core.api() + "?action=thumb&href=" + escapedHref + "&width=96&height=46&mode=rational";
|
||||
}
|
||||
|
||||
$label = $("<span class='label'>" + path.label + "</span>");
|
||||
$a = $("<a />")
|
||||
.attr("href", path.absHref)
|
||||
.click(function() { onClick(path, "extended"); })
|
||||
.appendTo($html)
|
||||
.append($("<span class='icon small'><img " + imgClass + " src='" + icon16 + "' alt='" + path.type + "' /></span>"))
|
||||
.append($("<span class='icon big'><img " + imgClass + " src='" + icon48 + "' alt='" + path.type + "' /></span>"))
|
||||
.append($label)
|
||||
.append($("<span class='date' data-time='" + path.time + "'></span>"))
|
||||
.append($("<span class='size' data-bytes='" + path.size + "'></span>"));
|
||||
|
||||
$a.hover(
|
||||
function () {
|
||||
if ($("#extended").hasClass("icons-view")) {
|
||||
var $this = $(this);
|
||||
$(".status.default").hide();
|
||||
$(".status.dynamic")
|
||||
.empty()
|
||||
.append($this.find(".label").clone())
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".date").clone())
|
||||
.show();
|
||||
|
||||
if (!$this.closest(".entry").hasClass("folder")) {
|
||||
$(".status.dynamic")
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".size").clone());
|
||||
}
|
||||
}
|
||||
},
|
||||
function () {
|
||||
$(".status.default").show();
|
||||
$(".status.dynamic").empty().hide();
|
||||
}
|
||||
);
|
||||
|
||||
if (path.isParentFolder) {
|
||||
if (!settings.setParentFolderLabels) {
|
||||
$label.addClass("l10n-parentDirectory");
|
||||
}
|
||||
$html.addClass("folder-parent");
|
||||
}
|
||||
|
||||
if (!isNaN(path.status)) {
|
||||
if (path.status === 200) {
|
||||
$html.addClass("page");
|
||||
$a.find(".icon.small img").attr("src", core.icon("folder-page"));
|
||||
$a.find(".icon.big img").attr("src", core.icon("folder-page", true));
|
||||
} else {
|
||||
$html.addClass("error");
|
||||
$label.append($("<span class='hint'> " + path.status + " </span>"));
|
||||
}
|
||||
}
|
||||
|
||||
if (path.html.$extended) {
|
||||
path.html.$extended.replaceWith($html);
|
||||
localize.formatDates();
|
||||
}
|
||||
path.html.$extended = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
updateTreeHtml = function (path) {
|
||||
|
||||
var $html, $blank, $a, $indicator, $ul, idx;
|
||||
|
||||
$html = $("<div class='entry' />")
|
||||
.data("path", path)
|
||||
.addClass(path.isFolder ? "folder" : "file");
|
||||
|
||||
$blank = $("<span class='blank' />").appendTo($html);
|
||||
|
||||
$a = $("<a />")
|
||||
.attr("href", path.absHref)
|
||||
.click(function() { onClick(path, "tree"); })
|
||||
.appendTo($html)
|
||||
.append($("<span class='icon'><img src='" + core.icon(path.type) + "' /></span>"))
|
||||
.append($("<span class='label'>" + path.label + "</span>"));
|
||||
|
||||
if (path.isFolder) {
|
||||
// indicator
|
||||
if (path.status === undefined || !path.isEmpty()) {
|
||||
$indicator = $("<span class='indicator initiated'><img src='" + core.image("tree") + "' /></span>")
|
||||
.click(function (event) {
|
||||
|
||||
var $entry = $indicator.closest(".entry"); // $html
|
||||
|
||||
if ($indicator.hasClass("unknown")) {
|
||||
fetchStatusAndContent(path.absHref, false, function (status, content) {
|
||||
|
||||
path.status = status;
|
||||
path.content = content;
|
||||
path.treeOpen = true;
|
||||
$("#tree").get(0).updateScrollbar(true);
|
||||
updateTreeHtml(path);
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
});
|
||||
} else if ($indicator.hasClass("open")) {
|
||||
path.treeOpen = false;
|
||||
$indicator.removeClass("open");
|
||||
$("#tree").get(0).updateScrollbar(true);
|
||||
$entry.find("> ul.content").slideUp(function() {
|
||||
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
});
|
||||
} else {
|
||||
path.treeOpen = true;
|
||||
$indicator.addClass("open");
|
||||
$("#tree").get(0).updateScrollbar(true);
|
||||
$entry.find("> ul.content").slideDown(function() {
|
||||
|
||||
$("#tree").get(0).updateScrollbar();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (path.status === undefined) {
|
||||
$indicator.addClass("unknown");
|
||||
} else if (path.treeOpen) {
|
||||
$indicator.addClass("open");
|
||||
}
|
||||
|
||||
$blank.replaceWith($indicator);
|
||||
}
|
||||
|
||||
// is path the domain?
|
||||
if (path.isDomain) {
|
||||
$html.addClass("domain");
|
||||
$a.find(".icon img").attr("src", core.icon("folder-home"));
|
||||
}
|
||||
|
||||
// is path the current folder?
|
||||
if (path.isCurrentFolder) {
|
||||
$html.addClass("current");
|
||||
$a.find(".icon img").attr("src", core.icon("folder-open"));
|
||||
}
|
||||
|
||||
// does it have subfolders?
|
||||
if (!path.isEmpty()) {
|
||||
$ul = $("<ul class='content' />").appendTo($html);
|
||||
$.each(path.content, function (idx, entry) {
|
||||
$("<li />").append(updateTreeHtml(entry)).appendTo($ul);
|
||||
});
|
||||
if (path.status === undefined || !path.treeOpen) {
|
||||
$ul.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// reflect folder status
|
||||
if (!isNaN(path.status)) {
|
||||
if (path.status === 200) {
|
||||
$a.find(".icon img").attr("src", core.icon("folder-page"));
|
||||
$a.append($("<span class='hint'><img src='" + core.image("page") + "' /></span>"));
|
||||
} else {
|
||||
$html.addClass("error");
|
||||
$a.append($("<span class='hint'>" + path.status + "</span>"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path.html.$tree) {
|
||||
path.html.$tree.replaceWith($html);
|
||||
}
|
||||
path.html.$tree = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
updateHtml = function (path) {
|
||||
|
||||
updateCrumbHtml(path);
|
||||
updateExtendedHtml(path);
|
||||
updateTreeHtml(path);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return {
|
||||
getPath: getPath,
|
||||
updatePaths: updatePaths,
|
||||
fetchStatusAndContent: fetchStatusAndContent,
|
||||
|
||||
updateCrumbHtml: updateCrumbHtml,
|
||||
updateExtendedHtml: updateExtendedHtml,
|
||||
updateTreeHtml: updateTreeHtml,
|
||||
updateHtml: updateHtml
|
||||
};
|
||||
});
|
|
@ -1,50 +0,0 @@
|
|||
|
||||
Module.define('context', [jQuery, 'settings'], function ($, settings) {
|
||||
|
||||
var $context,
|
||||
qrCodesSize,
|
||||
showQrCode = function ($a) {
|
||||
|
||||
var absHref = $a.attr('href'),
|
||||
url = 'http://' + document.domain + absHref;
|
||||
|
||||
$context.find('.qrcode').empty().qrcode({
|
||||
render: Modernizr.canvas ? 'canvas' : 'div',
|
||||
width: qrCodesSize,
|
||||
height: qrCodesSize,
|
||||
color: '#333',
|
||||
text: url
|
||||
});
|
||||
},
|
||||
init = function () {
|
||||
|
||||
qrCodesSize = settings.qrCodesSize;
|
||||
if (!qrCodesSize) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hideTimeoutId = null;
|
||||
|
||||
$context = $('<div id="context"><div class="qrcode"/></div>');
|
||||
$context.appendTo('body');
|
||||
|
||||
$('#extended')
|
||||
.on('mouseenter', '.entry.file a', function () {
|
||||
|
||||
showQrCode($(this));
|
||||
clearTimeout(hideTimeoutId);
|
||||
$context.stop(true, true).fadeIn(400);
|
||||
})
|
||||
.on('mouseleave', '.entry.file a', function () {
|
||||
|
||||
hideTimeoutId = setTimeout(function () {
|
||||
|
||||
$context.stop(true, true).fadeOut(400);
|
||||
}, 200);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
});
|
|
@ -1,311 +0,0 @@
|
|||
|
||||
Module.define('core', [jQuery, 'settings', 'types', 'util'], function ($, settings, types, util) {
|
||||
|
||||
var $window = $(window),
|
||||
extToFileType = (function (types) {
|
||||
var map = {};
|
||||
$.each(types, function (type, exts) {
|
||||
$.each(exts, function (idx, ext) {
|
||||
map[ext] = type;
|
||||
});
|
||||
});
|
||||
return map;
|
||||
}(types)),
|
||||
hash = function (obj) {
|
||||
|
||||
if ($.isPlainObject(obj)) {
|
||||
var hashStr = '';
|
||||
$.each($.extend({}, hash(), obj), function (key, value) {
|
||||
if (value) {
|
||||
hashStr += '/' + encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
||||
}
|
||||
});
|
||||
hashStr = '#!' + hashStr;
|
||||
// window.location.hash = hashStr;
|
||||
return hashStr;
|
||||
} else {
|
||||
var result = {},
|
||||
parts = document.location.hash.split('/');
|
||||
|
||||
if (parts.length >= 2 || parts[0] === '#!') {
|
||||
parts.shift();
|
||||
$.each(parts, function (idx, part) {
|
||||
|
||||
var match = /^([^=]*)=(.*?)$/.exec(part);
|
||||
if (match) {
|
||||
result[decodeURIComponent(match[1])] = decodeURIComponent(match[2]);
|
||||
}
|
||||
});
|
||||
}
|
||||
return typeof obj === 'string' ? result[obj] : result;
|
||||
}
|
||||
},
|
||||
api = function () {
|
||||
|
||||
return settings.h5aiAbsHref + "php/api.php";
|
||||
},
|
||||
image = function (id, noPngExt) {
|
||||
|
||||
return settings.h5aiAbsHref + "images/" + id + (noPngExt ? "" : ".png");
|
||||
},
|
||||
icon = function (id, big) {
|
||||
|
||||
return settings.h5aiAbsHref + "icons/" + (big ? "48x48" : "16x16") + "/" + id + ".png";
|
||||
},
|
||||
viewmode = function (viewmode) {
|
||||
|
||||
var $viewDetails = $("#viewdetails"),
|
||||
$viewIcons = $("#viewicons"),
|
||||
$extended = $("#extended");
|
||||
|
||||
if (viewmode) {
|
||||
amplify.store(settings.store.viewmode, viewmode);
|
||||
} else {
|
||||
viewmode = amplify.store(settings.store.viewmode);
|
||||
}
|
||||
viewmode = $.inArray(viewmode, settings.viewmodes) >= 0 ? viewmode : settings.viewmodes[0];
|
||||
hash({view: viewmode});
|
||||
|
||||
$viewDetails.add($viewIcons).removeClass("current");
|
||||
if (viewmode === "details") {
|
||||
$viewDetails.addClass("current");
|
||||
$extended.addClass("details-view").removeClass("icons-view").show();
|
||||
} else if (viewmode === "icons") {
|
||||
$viewIcons.addClass("current");
|
||||
$extended.removeClass("details-view").addClass("icons-view").show();
|
||||
} else {
|
||||
$extended.hide();
|
||||
}
|
||||
},
|
||||
initTopSpace = function () {
|
||||
|
||||
var $body = $("body"),
|
||||
$tree = $("#tree"),
|
||||
adjustTopSpace = function () {
|
||||
|
||||
var winHeight = $window.height(),
|
||||
navHeight = $("body > nav").outerHeight(),
|
||||
footerHeight = $("body > footer").outerHeight(),
|
||||
contentSpacing = 50,
|
||||
treeSpacing = 0;
|
||||
|
||||
$body.css({
|
||||
"margin-top": navHeight + contentSpacing,
|
||||
"margin-bottom": footerHeight + contentSpacing
|
||||
});
|
||||
|
||||
$tree.css({
|
||||
top: navHeight + treeSpacing,
|
||||
height: winHeight - navHeight - footerHeight - 16 - 2 * treeSpacing
|
||||
});
|
||||
|
||||
try {
|
||||
$tree.get(0).updateScrollbar();
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
$window.resize(function () {
|
||||
adjustTopSpace();
|
||||
});
|
||||
adjustTopSpace();
|
||||
},
|
||||
initViews = function () {
|
||||
|
||||
var $navbar = $("#navbar"),
|
||||
$extended = $("#extended");
|
||||
|
||||
$("#table").remove();
|
||||
|
||||
if (settings.viewmodes.length > 1) {
|
||||
if ($.inArray("icons", settings.viewmodes) >= 0) {
|
||||
$("<li id='viewicons' class='view'><a href='#'><img alt='view-icons' /><span class='l10n-icons'>icons</span></a></li>")
|
||||
.find("img").attr("src", image("view-icons")).end()
|
||||
.find("a").click(function (event) {
|
||||
viewmode("icons");
|
||||
event.preventDefault();
|
||||
}).end()
|
||||
.appendTo($navbar);
|
||||
}
|
||||
if ($.inArray("details", settings.viewmodes) >= 0) {
|
||||
$("<li id='viewdetails' class='view'><a href='#'><img alt='view-details' /><span class='l10n-details'>details</span></a></li>")
|
||||
.find("img").attr("src", image("view-details")).end()
|
||||
.find("a").click(function (event) {
|
||||
viewmode("details");
|
||||
event.preventDefault();
|
||||
}).end()
|
||||
.appendTo($navbar);
|
||||
}
|
||||
}
|
||||
|
||||
// status update
|
||||
$extended.find(".entry a").hover(
|
||||
function () {
|
||||
if ($extended.hasClass("icons-view")) {
|
||||
var $this = $(this);
|
||||
$(".status.default").hide();
|
||||
$(".status.dynamic")
|
||||
.empty()
|
||||
.append($this.find(".label").clone())
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".date").clone())
|
||||
.show();
|
||||
|
||||
if (!$this.closest(".entry").hasClass("folder")) {
|
||||
$(".status.dynamic")
|
||||
.append($("<span class='sep'>·</span>"))
|
||||
.append($this.find(".size").clone());
|
||||
}
|
||||
}
|
||||
},
|
||||
function () {
|
||||
$(".status.default").show();
|
||||
$(".status.dynamic").empty().hide();
|
||||
}
|
||||
);
|
||||
},
|
||||
shiftTree = function (forceVisible, dontAnimate) {
|
||||
|
||||
var $tree = $("#tree"),
|
||||
$extended = $("#extended");
|
||||
|
||||
if ((settings.slideTree && $tree.outerWidth() < $extended.offset().left) || forceVisible) {
|
||||
if (dontAnimate) {
|
||||
$tree.stop().css({ left: 0 });
|
||||
} else {
|
||||
$tree.stop().animate({ left: 0 });
|
||||
}
|
||||
} else {
|
||||
if (dontAnimate) {
|
||||
$tree.stop().css({ left: 18 - $tree.outerWidth() });
|
||||
} else {
|
||||
$tree.stop().animate({ left: 18 - $tree.outerWidth() });
|
||||
}
|
||||
}
|
||||
},
|
||||
initTree = function () {
|
||||
|
||||
$("#tree").hover(
|
||||
function () { shiftTree(true); },
|
||||
function () { shiftTree(); }
|
||||
);
|
||||
$window.resize(function () { shiftTree(); });
|
||||
shiftTree(false, true);
|
||||
},
|
||||
selectLinks = function (href) {
|
||||
|
||||
var elements = [];
|
||||
$("a[href^='/']").each(function () {
|
||||
|
||||
if ($(this).attr("href") === href) {
|
||||
elements.push(this);
|
||||
}
|
||||
});
|
||||
return $(elements);
|
||||
},
|
||||
linkHoverStates = function () {
|
||||
|
||||
if (settings.linkHoverStates) {
|
||||
$("a[href^='/']:not(.linkedHoverStates)").each(function () {
|
||||
|
||||
var $a = $(this).addClass("linkedHoverStates"),
|
||||
href = $a.attr("href");
|
||||
|
||||
$a.hover(
|
||||
function () { selectLinks(href).addClass("hover"); },
|
||||
function () { selectLinks(href).removeClass("hover"); }
|
||||
);
|
||||
});
|
||||
}
|
||||
},
|
||||
onIndicatorClick = function (event) {
|
||||
|
||||
var $indicator = $(this),
|
||||
$entry = $indicator.closest(".entry"),
|
||||
updateTreeScrollbar = $("#tree").get(0).updateScrollbar;
|
||||
|
||||
if ($indicator.hasClass("unknown")) {
|
||||
$.get(api(), { "action": "tree", "href": $entry.find("> a").attr("href") }, function (html) {
|
||||
|
||||
var $content = $(html);
|
||||
|
||||
$indicator.removeClass("unknown");
|
||||
if ($content.find("> li").size() === 0) {
|
||||
$indicator.replaceWith($("<span class='blank' />"));
|
||||
} else {
|
||||
$indicator.addClass("open");
|
||||
$entry.find("> .content").replaceWith($content);
|
||||
updateTreeScrollbar();
|
||||
$content.find(".indicator:not(.initiated)")
|
||||
.click(onIndicatorClick)
|
||||
.addClass("initiated");
|
||||
}
|
||||
});
|
||||
} else if ($indicator.hasClass("open")) {
|
||||
$indicator.removeClass("open");
|
||||
updateTreeScrollbar(true);
|
||||
$entry.find("> .content").slideUp(function () {
|
||||
updateTreeScrollbar();
|
||||
});
|
||||
} else {
|
||||
$indicator.addClass("open");
|
||||
updateTreeScrollbar(true);
|
||||
$entry.find("> .content").slideDown(function () {
|
||||
updateTreeScrollbar();
|
||||
});
|
||||
}
|
||||
},
|
||||
initIndicators = function () {
|
||||
|
||||
$("#tree .entry.folder .indicator:not(.initiated)")
|
||||
.click(onIndicatorClick)
|
||||
.addClass("initiated");
|
||||
},
|
||||
getFileType = function (filename) {
|
||||
|
||||
var dotidx = filename.lastIndexOf('.'),
|
||||
ext = dotidx >= 0 ? filename.substr(dotidx) : filename;
|
||||
|
||||
return extToFileType[ext.toLowerCase()] || "unknown";
|
||||
},
|
||||
formatSizes = function () {
|
||||
|
||||
$("#extended .entry .size").each(function () {
|
||||
|
||||
var $this = $(this),
|
||||
bytes = $this.data("bytes"),
|
||||
formattedSize = bytes >= 0 ? util.formatSize(bytes) : "";
|
||||
|
||||
$this.text(formattedSize);
|
||||
});
|
||||
},
|
||||
setTotals = function () {
|
||||
|
||||
var $extended = $("#extended");
|
||||
|
||||
$(".folderTotal").text($extended.find(".entry.folder:not(.folder-parent)").length);
|
||||
$(".fileTotal").text($extended.find(".entry.file").length);
|
||||
},
|
||||
init = function () {
|
||||
|
||||
initViews();
|
||||
viewmode();
|
||||
initTopSpace();
|
||||
initTree();
|
||||
linkHoverStates();
|
||||
formatSizes();
|
||||
setTotals();
|
||||
initIndicators();
|
||||
};
|
||||
|
||||
return {
|
||||
init: init,
|
||||
hash: hash,
|
||||
api: api,
|
||||
image: image,
|
||||
icon: icon,
|
||||
shiftTree: shiftTree,
|
||||
linkHoverStates: linkHoverStates,
|
||||
initIndicators: initIndicators,
|
||||
getFileType: getFileType
|
||||
};
|
||||
});
|
16
src/_h5ai/js/inc/core/entry.js
Normal file
16
src/_h5ai/js/inc/core/entry.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
|
||||
module.define('core/entry', [jQuery, 'core/parser', 'model/entry'], function ($, parser, Entry) {
|
||||
|
||||
var absHref = document.location.pathname;
|
||||
|
||||
parser.parse(absHref, $('body'));
|
||||
$('#data-apache-autoindex').remove();
|
||||
|
||||
var entry = Entry.get(absHref);
|
||||
entry.status = 'h5ai';
|
||||
if (entry.parent) {
|
||||
entry.parent.isParentFolder = true;
|
||||
}
|
||||
|
||||
return entry;
|
||||
});
|
25
src/_h5ai/js/inc/core/event.js
Normal file
25
src/_h5ai/js/inc/core/event.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
module.define('core/event', [amplify], function (amplify) {
|
||||
|
||||
var sub = function (topic, callback) {
|
||||
|
||||
amplify.subscribe(topic, callback);
|
||||
},
|
||||
|
||||
unsub = function (topic, callback) {
|
||||
|
||||
amplify.unsubscribe(topic, callback);
|
||||
},
|
||||
|
||||
pub = function (topic, data) {
|
||||
|
||||
// console.log('EVENT PUB', topic, data);
|
||||
amplify.publish(topic, data);
|
||||
};
|
||||
|
||||
return {
|
||||
sub: sub,
|
||||
unsub: unsub,
|
||||
pub: pub
|
||||
};
|
||||
});
|
80
src/_h5ai/js/inc/core/format.js
Normal file
80
src/_h5ai/js/inc/core/format.js
Normal file
|
@ -0,0 +1,80 @@
|
|||
|
||||
module.define('core/format', [moment], function (moment) {
|
||||
|
||||
var reParseSize = /^\s*([\.\d]+)\s*([kmgt]?)b?\s*$/i,
|
||||
treshhold = 1000.0,
|
||||
kilo = 1000.0,
|
||||
sizeUnits = ['B', 'KB', 'MB', 'GB', 'TB'],
|
||||
|
||||
parseSize = function (str) {
|
||||
|
||||
var match = reParseSize.exec(str),
|
||||
val, unit;
|
||||
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
val = parseFloat(match[1]);
|
||||
unit = match[2].toLowerCase();
|
||||
if (unit === 'k') {
|
||||
val *= kilo;
|
||||
} else if (unit === 'm') {
|
||||
val *= kilo * kilo;
|
||||
} else if (unit === 'g') {
|
||||
val *= kilo * kilo * kilo;
|
||||
} else if (unit === 't') {
|
||||
val *= kilo * kilo * kilo * kilo;
|
||||
}
|
||||
return val;
|
||||
},
|
||||
|
||||
formatSize = function (size) {
|
||||
|
||||
if (!_.isNumber(size) || size < 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var i = 0,
|
||||
maxI = sizeUnits.length - 1;
|
||||
|
||||
while (size >= treshhold && i < maxI) {
|
||||
size /= kilo;
|
||||
i += 1;
|
||||
}
|
||||
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + sizeUnits[i];
|
||||
},
|
||||
|
||||
defaultDateFormat = 'YYYY-MM-DD HH:mm',
|
||||
|
||||
setDefaultDateFormat = function (dateFormat) {
|
||||
|
||||
defaultDateFormat = dateFormat;
|
||||
},
|
||||
|
||||
parseDate = function (str, dateFormat) {
|
||||
|
||||
try { // problems with ie < 9 :(
|
||||
return moment(str, dateFormat || defaultDateFormat).valueOf() || null;
|
||||
} catch (err) {}
|
||||
|
||||
return Date.parse(str).valueOf() || null;
|
||||
},
|
||||
|
||||
formatDate = function (millis, dateFormat) {
|
||||
|
||||
if (!_.isNumber(millis) || !millis) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return moment(millis).format(dateFormat || defaultDateFormat);
|
||||
};
|
||||
|
||||
return {
|
||||
parseSize: parseSize,
|
||||
formatSize: formatSize,
|
||||
setDefaultDateFormat: setDefaultDateFormat,
|
||||
parseDate: parseDate,
|
||||
formatDate: formatDate
|
||||
};
|
||||
});
|
9
src/_h5ai/js/inc/core/parser.js
Normal file
9
src/_h5ai/js/inc/core/parser.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
|
||||
module.define('core/parser', [jQuery], function ($) {
|
||||
|
||||
if ($('#data-generic-json').length) {
|
||||
return module.require('parser/generic-json');
|
||||
}
|
||||
|
||||
return module.require('parser/apache-autoindex');
|
||||
});
|
22
src/_h5ai/js/inc/core/resource.js
Normal file
22
src/_h5ai/js/inc/core/resource.js
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
module.define('core/resource', ['core/settings'], function (settings) {
|
||||
|
||||
var api = function () {
|
||||
|
||||
return settings.h5aiAbsHref + 'php/api.php';
|
||||
},
|
||||
image = function (id, noPngExt) {
|
||||
|
||||
return settings.h5aiAbsHref + 'images/' + id + (noPngExt ? '' : '.png');
|
||||
},
|
||||
icon = function (id, big) {
|
||||
|
||||
return settings.h5aiAbsHref + 'icons/' + (big ? '48x48' : '16x16') + '/' + id + '.png';
|
||||
};
|
||||
|
||||
return {
|
||||
api: api,
|
||||
image: image,
|
||||
icon: icon
|
||||
};
|
||||
});
|
32
src/_h5ai/js/inc/core/settings.js
Normal file
32
src/_h5ai/js/inc/core/settings.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
|
||||
module.define('core/config', [H5AI_CONFIG], function (config) {
|
||||
|
||||
var defaults = {
|
||||
rootAbsHref: '/',
|
||||
h5aiAbsHref: '/_h5ai/',
|
||||
};
|
||||
|
||||
return {
|
||||
settings: _.extend({}, defaults, config.options),
|
||||
types: _.extend({}, config.types),
|
||||
langs: _.extend({}, config.langs)
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
module.define('core/settings', ['core/config'], function (config) {
|
||||
|
||||
return config.settings;
|
||||
});
|
||||
|
||||
|
||||
module.define('core/types', ['core/config'], function (config) {
|
||||
|
||||
return config.types;
|
||||
});
|
||||
|
||||
|
||||
module.define('core/langs', ['core/config'], function (config) {
|
||||
|
||||
return config.langs;
|
||||
});
|
18
src/_h5ai/js/inc/core/store.js
Normal file
18
src/_h5ai/js/inc/core/store.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
module.define('core/store', [amplify], function (amplify) {
|
||||
|
||||
var put = function (key, value) {
|
||||
|
||||
amplify.store(key, value);
|
||||
},
|
||||
|
||||
get = function (key) {
|
||||
|
||||
return amplify.store(key);
|
||||
};
|
||||
|
||||
return {
|
||||
put: put,
|
||||
get: get
|
||||
};
|
||||
});
|
84
src/_h5ai/js/inc/ext/crumb.js
Normal file
84
src/_h5ai/js/inc/ext/crumb.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
|
||||
module.define('ext/crumb', [jQuery, 'core/settings', 'core/resource', 'core/entry'], function ($, allsettings, resource, entry) {
|
||||
|
||||
var defaults = {
|
||||
enabled: true
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.crumb),
|
||||
|
||||
template = '<li class="crumb">' +
|
||||
'<a>' +
|
||||
'<img src="' + resource.image('crumb') + '" alt=">" />' +
|
||||
'<span />' +
|
||||
'</a>' +
|
||||
'</li>',
|
||||
pageHintTemplate = '<img class="hint" src="' + resource.image('page') + '" alt="has index page" />',
|
||||
statusHintTemplate = '<span class="hint"></span>',
|
||||
|
||||
// updates the crumb for this single entry
|
||||
update = function (entry) {
|
||||
|
||||
if (entry.$crumb && entry.$crumb.data('status') === entry.status) {
|
||||
return entry.$crumb;
|
||||
}
|
||||
|
||||
var $html = $(template),
|
||||
$a = $html.find('a');
|
||||
|
||||
$html
|
||||
.addClass(entry.isFolder() ? 'folder' : 'file')
|
||||
.data('status', entry.status);
|
||||
|
||||
$a
|
||||
.attr('href', entry.absHref)
|
||||
.find('span').text(entry.label).end();
|
||||
|
||||
if (entry.isDomain()) {
|
||||
$html.addClass('domain');
|
||||
$a.find('img').attr('src', resource.image('home'));
|
||||
}
|
||||
|
||||
if (entry.isCurrentFolder()) {
|
||||
$html.addClass('current');
|
||||
}
|
||||
|
||||
if (_.isNumber(entry.status)) {
|
||||
if (entry.status === 200) {
|
||||
$a.append($(pageHintTemplate));
|
||||
} else {
|
||||
$a.append($(statusHintTemplate).text('(' + entry.status + ')'));
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.$crumb) {
|
||||
entry.$crumb.replaceWith($html);
|
||||
}
|
||||
entry.$crumb = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
|
||||
// creates the complete crumb from entry down to the root
|
||||
init = function (entry) {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var crumb = entry.getCrumb(),
|
||||
$ul = $('#navbar');
|
||||
|
||||
_.each(crumb, function (e) {
|
||||
|
||||
$ul.append(update(e));
|
||||
|
||||
e.fetchStatus(function (e) {
|
||||
|
||||
update(e);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
init(entry);
|
||||
});
|
42
src/_h5ai/js/inc/ext/custom.js
Normal file
42
src/_h5ai/js/inc/ext/custom.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
module.define('ext/custom', [jQuery, 'core/settings'], function ($, allsettings) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false,
|
||||
header: '_h5ai.header.html',
|
||||
footer: '_h5ai.footer.html'
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.custom),
|
||||
|
||||
init = function () {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_.isString(settings.header)) {
|
||||
$.ajax({
|
||||
url: settings.header,
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
|
||||
$('<div id="content-header">' + data + '</div>').prependTo('#content');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (_.isString(settings.footer)) {
|
||||
$.ajax({
|
||||
url: settings.footer,
|
||||
dataType: 'html',
|
||||
success: function (data) {
|
||||
|
||||
$('<div id="content-footer">' + data + '</div>').appendTo('#content');
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
123
src/_h5ai/js/inc/ext/filter.js
Normal file
123
src/_h5ai/js/inc/ext/filter.js
Normal file
|
@ -0,0 +1,123 @@
|
|||
|
||||
module.define('ext/filter', [jQuery, 'core/settings', 'core/resource'], function ($, allsettings, resource) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.filter),
|
||||
|
||||
template = '<li id="filter">' +
|
||||
'<span class="element">' +
|
||||
'<img src="' + resource.image('filter') + '" alt="filter" />' +
|
||||
'<input type="text" value="" placeholder="filter" />' +
|
||||
'</span>' +
|
||||
'</li>',
|
||||
noMatchTemplate = '<div class="no-match l10n-noMatch">no match</div>',
|
||||
|
||||
$filter, $input, $noMatch,
|
||||
|
||||
filter = function (re) {
|
||||
|
||||
var match = [],
|
||||
noMatch = [],
|
||||
duration = 200;
|
||||
|
||||
if (re) {
|
||||
$('#extended .entry').each(function () {
|
||||
|
||||
var label = $(this).find('.label').text();
|
||||
|
||||
if (label.match(re)) {
|
||||
match.push(this);
|
||||
} else {
|
||||
noMatch.push(this);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
match = $('#extended .entry');
|
||||
}
|
||||
|
||||
if ($(match).length) {
|
||||
$noMatch.hide();
|
||||
} else {
|
||||
setTimeout(function () { $noMatch.show(); }, duration);
|
||||
}
|
||||
$(match).fadeIn(duration);
|
||||
$(noMatch).fadeOut(duration);
|
||||
},
|
||||
|
||||
checkState = function (focus) {
|
||||
|
||||
var val = $input.val();
|
||||
|
||||
if (val || focus) {
|
||||
$filter.addClass('current');
|
||||
} else {
|
||||
$filter.removeClass('current');
|
||||
}
|
||||
},
|
||||
|
||||
escapeRegExp = function (sequence) {
|
||||
|
||||
return sequence.replace(/[\-\[\]{}()*+?.,\\$\^|#\s]/g, '\\$&');
|
||||
// return sequence.replace(/[|()\[{.+*?^$\\]/g,"\\$0");
|
||||
},
|
||||
|
||||
parseFilterSequence = function (sequence) {
|
||||
|
||||
if (sequence.substr(0, 3) === 're:') {
|
||||
return new RegExp(sequence.substr(3));
|
||||
}
|
||||
|
||||
sequence = $.map($.trim(sequence).split(/\s+/), function (part) {
|
||||
|
||||
return escapeRegExp(part);
|
||||
}).join('|');
|
||||
|
||||
return new RegExp(sequence);
|
||||
},
|
||||
|
||||
update = function () {
|
||||
|
||||
var val = $input.val();
|
||||
|
||||
if (val) {
|
||||
filter(parseFilterSequence(val));
|
||||
} else {
|
||||
filter();
|
||||
}
|
||||
checkState($input.is(':focus'));
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$filter = $(template);
|
||||
$input = $filter.find('input');
|
||||
$noMatch = $(noMatchTemplate).appendTo($('#extended'));
|
||||
|
||||
$filter
|
||||
.on('click', function () {
|
||||
|
||||
$input.focus();
|
||||
})
|
||||
.appendTo($('#navbar'));
|
||||
|
||||
$input
|
||||
.on('focus', function () {
|
||||
|
||||
checkState(true);
|
||||
})
|
||||
.on('blur', function () {
|
||||
|
||||
checkState(false);
|
||||
})
|
||||
.on('keyup', update);
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
14
src/_h5ai/js/inc/ext/folderstatus.js
Normal file
14
src/_h5ai/js/inc/ext/folderstatus.js
Normal file
|
@ -0,0 +1,14 @@
|
|||
|
||||
module.define('ext/folderstatus', [jQuery, 'core/settings'], function ($, allsettings) {
|
||||
|
||||
var defaults = {
|
||||
enabled: true,
|
||||
folders: {}
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.folderstatus),
|
||||
|
||||
folders = settings.enabled ? settings.folders : defaults.folders;
|
||||
|
||||
return folders;
|
||||
});
|
|
@ -1,26 +1,29 @@
|
|||
|
||||
Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, settings, langs, core) {
|
||||
module.define('ext/l10n', [jQuery, 'core/settings', 'core/langs', 'core/format', 'core/store'], function ($, allsettings, langs, format, store) {
|
||||
|
||||
var currentDateFormat = settings.dateFormat,
|
||||
formatDates = function (dateFormat) {
|
||||
|
||||
if (dateFormat) {
|
||||
currentDateFormat = dateFormat;
|
||||
}
|
||||
|
||||
$('#extended .entry .date').each(function () {
|
||||
|
||||
var $this = $(this),
|
||||
time = $this.data('time'),
|
||||
formattedDate = time ? moment(time).format(currentDateFormat) : '';
|
||||
|
||||
$this.text(formattedDate);
|
||||
});
|
||||
var defaults = {
|
||||
enabled: true,
|
||||
lang: "en",
|
||||
useBrowserLang: true,
|
||||
defaultDateFormat: 'YYYY-MM-DD HH:mm'
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.l10n),
|
||||
|
||||
template = '<span id="langSelector">' +
|
||||
'<span class="lang">en</span> - <span class="l10n-lang">english</span>' +
|
||||
'<span class="langOptions"> <ul /> </span>' +
|
||||
'</span>',
|
||||
langOptionTemplate = '<li class="langOption" />',
|
||||
|
||||
storekey = 'h5ai.language',
|
||||
|
||||
currentLang = null,
|
||||
|
||||
localize = function (langs, lang, useBrowserLang) {
|
||||
|
||||
var storedLang = amplify.store(settings.store.lang),
|
||||
browserLang, selected, key;
|
||||
var storedLang = store.get(storekey),
|
||||
browserLang, key;
|
||||
|
||||
if (langs[storedLang]) {
|
||||
lang = storedLang;
|
||||
|
@ -39,38 +42,45 @@ Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, se
|
|||
lang = 'en';
|
||||
}
|
||||
|
||||
selected = langs[lang];
|
||||
if (selected) {
|
||||
$.each(selected, function (key, value) {
|
||||
currentLang = langs[lang];
|
||||
if (currentLang) {
|
||||
$.each(currentLang, function (key, value) {
|
||||
$('.l10n-' + key).text(value);
|
||||
});
|
||||
$('.lang').text(lang);
|
||||
$('.langOption').removeClass('current');
|
||||
$('.langOption.' + lang).addClass('current');
|
||||
core.hash({lang: lang});
|
||||
}
|
||||
|
||||
formatDates(selected.dateFormat || settings.dateFormat);
|
||||
format.setDefaultDateFormat(currentLang.dateFormat || settings.defaultDateFormat);
|
||||
|
||||
$('#extended .entry .date').each(function () {
|
||||
|
||||
var $this = $(this);
|
||||
|
||||
$this.text(format.formatDate($this.data('time')));
|
||||
});
|
||||
},
|
||||
|
||||
initLangSelector = function (langs) {
|
||||
|
||||
var $langOptions = $('#langSelector .langOptions'),
|
||||
sortedLangsKeys = [],
|
||||
$ul;
|
||||
var $langSelector = $(template).appendTo('#bottombar .right'),
|
||||
$langOptions = $langSelector.find('.langOptions'),
|
||||
$ul = $langOptions.find('ul'),
|
||||
sortedLangsKeys = [];
|
||||
|
||||
$.each(langs, function (lang) {
|
||||
sortedLangsKeys.push(lang);
|
||||
});
|
||||
sortedLangsKeys.sort();
|
||||
|
||||
$ul = $('<ul />');
|
||||
$.each(sortedLangsKeys, function (idx, lang) {
|
||||
$('<li class="langOption" />')
|
||||
$(langOptionTemplate)
|
||||
.addClass(lang)
|
||||
.text(lang + ' - ' + langs[lang].lang)
|
||||
.appendTo($ul)
|
||||
.click(function () {
|
||||
amplify.store(settings.store.lang, lang);
|
||||
store.put(storekey, lang);
|
||||
localize(langs, lang, false);
|
||||
});
|
||||
});
|
||||
|
@ -78,7 +88,7 @@ Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, se
|
|||
.append($ul)
|
||||
.scrollpanel();
|
||||
|
||||
$('#langSelector').hover(
|
||||
$langSelector.hover(
|
||||
function () {
|
||||
$langOptions
|
||||
.css('top', '-' + $langOptions.outerHeight() + 'px')
|
||||
|
@ -93,15 +103,16 @@ Module.define('localize', [jQuery, 'settings', 'langs', 'core'], function ($, se
|
|||
}
|
||||
);
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
initLangSelector(langs);
|
||||
localize(langs, settings.lang, settings.useBrowserLang);
|
||||
};
|
||||
|
||||
return {
|
||||
init: init,
|
||||
formatDates: formatDates
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
44
src/_h5ai/js/inc/ext/link-hover-states.js
Normal file
44
src/_h5ai/js/inc/ext/link-hover-states.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
|
||||
module.define('ext/link-hover-states', [jQuery, 'core/settings'], function ($, allsettings) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings['link-hover-states']),
|
||||
|
||||
selector = "a[href^='/']",
|
||||
|
||||
selectLinks = function (href) {
|
||||
|
||||
return $(_.filter($(selector), function (el) {
|
||||
|
||||
return $(el).attr('href') === href;
|
||||
}));
|
||||
},
|
||||
|
||||
onMouseEnter = function () {
|
||||
|
||||
var href = $(this).attr('href');
|
||||
|
||||
selectLinks(href).addClass('hover');
|
||||
},
|
||||
|
||||
onMouseLeave = function () {
|
||||
|
||||
var href = $(this).attr('href');
|
||||
|
||||
selectLinks(href).removeClass('hover');
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
if (settings.enabled) {
|
||||
$('body')
|
||||
.on('mouseenter', selector, onMouseEnter)
|
||||
.on('mouseleave', selector, onMouseLeave);
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
56
src/_h5ai/js/inc/ext/qrcode.js
Normal file
56
src/_h5ai/js/inc/ext/qrcode.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
module.define('ext/qrcode', [jQuery, 'core/settings', 'core/event'], function ($, allsettings, event) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false,
|
||||
size: 150
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.qrcode),
|
||||
|
||||
template = '<div id="context"><div class="qrcode" /></div>',
|
||||
|
||||
$context, hideTimeoutId,
|
||||
|
||||
update = function (entry) {
|
||||
|
||||
$context.find('.qrcode').empty().qrcode({
|
||||
render: Modernizr.canvas ? 'canvas' : 'div',
|
||||
width: settings.size,
|
||||
height: settings.size,
|
||||
color: '#333',
|
||||
text: 'http://' + document.domain + entry.absHref
|
||||
});
|
||||
},
|
||||
|
||||
onMouseenter = function (entry) {
|
||||
|
||||
if (!entry.isFolder()) {
|
||||
update(entry);
|
||||
clearTimeout(hideTimeoutId);
|
||||
$context.stop(true, true).fadeIn(400);
|
||||
}
|
||||
},
|
||||
|
||||
onMouseleave = function (entry) {
|
||||
|
||||
hideTimeoutId = setTimeout(function () {
|
||||
|
||||
$context.stop(true, true).fadeOut(400);
|
||||
}, 200);
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$context = $(template).appendTo('body');
|
||||
|
||||
event.sub('entry.mouseenter', onMouseenter);
|
||||
event.sub('entry.mouseleave', onMouseleave);
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
114
src/_h5ai/js/inc/ext/select.js
Normal file
114
src/_h5ai/js/inc/ext/select.js
Normal file
|
@ -0,0 +1,114 @@
|
|||
|
||||
module.define('ext/select', [jQuery, 'core/settings', 'core/event'], function ($, allsettings, event) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.select),
|
||||
|
||||
x = 0,
|
||||
y = 0,
|
||||
$document = $(document),
|
||||
$selectionRect = $('<div id="selection-rect"></div>'),
|
||||
|
||||
publish = function () {
|
||||
|
||||
var entries = _.map($('#extended .entry.selected'), function (entryElement) {
|
||||
|
||||
return $(entryElement).data('entry');
|
||||
});
|
||||
|
||||
event.pub('selection', entries);
|
||||
},
|
||||
|
||||
selectionUpdate = function (event) {
|
||||
|
||||
var l = Math.min(x, event.pageX),
|
||||
t = Math.min(y, event.pageY),
|
||||
w = Math.abs(x - event.pageX),
|
||||
h = Math.abs(y - event.pageY),
|
||||
selRect;
|
||||
|
||||
event.preventDefault();
|
||||
$selectionRect.css({left: l, top: t, width: w, height: h});
|
||||
|
||||
selRect = $selectionRect.fracs('rect');
|
||||
$('#extended .entry').removeClass('selecting').each(function () {
|
||||
|
||||
var $entry = $(this),
|
||||
rect = $entry.find('a').fracs('rect'),
|
||||
inter = selRect.intersection(rect);
|
||||
if (inter && !$entry.hasClass('folder-parent')) {
|
||||
$entry.addClass('selecting');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
selectionEnd = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$document.off('mousemove', selectionUpdate);
|
||||
$selectionRect.hide().css({left: 0, top: 0, width: 0, height: 0});
|
||||
$('#extended .entry.selecting.selected').removeClass('selecting').removeClass('selected');
|
||||
$('#extended .entry.selecting').removeClass('selecting').addClass('selected');
|
||||
publish();
|
||||
},
|
||||
|
||||
selectionStart = function (event) {
|
||||
|
||||
var view = $(document).fracs('viewport');
|
||||
|
||||
x = event.pageX;
|
||||
y = event.pageY;
|
||||
// only on left button and don't block the scrollbars
|
||||
if (event.button !== 0 || x >= view.right || y >= view.bottom) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
$(':focus').blur();
|
||||
if (!event.ctrlKey) {
|
||||
$('#extended .entry').removeClass('selected');
|
||||
publish();
|
||||
}
|
||||
$selectionRect.show().css({left: x, top: y, width: 0, height: 0});
|
||||
|
||||
$document
|
||||
.on('mousemove', selectionUpdate)
|
||||
.one('mouseup', selectionEnd);
|
||||
},
|
||||
|
||||
noSelection = function (event) {
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
return false;
|
||||
},
|
||||
|
||||
noSelectionUnlessCtrl = function (event) {
|
||||
|
||||
if (!event.ctrlKey) {
|
||||
noSelection(event);
|
||||
}
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$selectionRect.hide().appendTo($('body'));
|
||||
|
||||
// $('#topbar,#bottombar,#tree,input').on('mousedown', noSelection);
|
||||
// $('#content').on('mousedown', 'a', noSelectionUnlessCtrl);
|
||||
// $document.on('mousedown', selectionStart);
|
||||
|
||||
$document
|
||||
.on('mousedown', '.noSelection', noSelection)
|
||||
.on('mousedown', '.noSelectionUnlessCtrl,input,a', noSelectionUnlessCtrl)
|
||||
.on('mousedown', selectionStart);
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
|
@ -1,7 +1,16 @@
|
|||
|
||||
Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core) {
|
||||
module.define('ext/sort', [jQuery, 'core/settings', 'core/resource', 'core/store'], function ($, allsettings, resource, store) {
|
||||
|
||||
var type = function (entry) {
|
||||
var defaults = {
|
||||
enabled: false,
|
||||
order: 'na'
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.sort),
|
||||
|
||||
storekey = 'h5ai.sortorder',
|
||||
|
||||
type = function (entry) {
|
||||
|
||||
var $entry = $(entry);
|
||||
|
||||
|
@ -54,17 +63,21 @@ Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core)
|
|||
|
||||
var order = orders[id];
|
||||
|
||||
store.put(storekey, id);
|
||||
|
||||
$all.removeClass('ascending').removeClass('descending');
|
||||
order.head.addClass(order.clas);
|
||||
$('#extended .entry').detach().sort(order.fn).appendTo($('#extended > ul'));
|
||||
core.hash({sort: id});
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
var $ascending = $('<img src="' + core.image('ascending') + '" class="sort ascending" alt="ascending" />'),
|
||||
$descending = $('<img src="' + core.image('descending') + '" class="sort descending" alt="descending" />'),
|
||||
initialOrder = core.hash('sort'),
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $ascending = $('<img src="' + resource.image('ascending') + '" class="sort ascending" alt="ascending" />'),
|
||||
$descending = $('<img src="' + resource.image('descending') + '" class="sort descending" alt="descending" />'),
|
||||
$header = $('#extended li.header'),
|
||||
$label = $header.find('a.label'),
|
||||
$date = $header.find('a.date'),
|
||||
|
@ -104,7 +117,7 @@ Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core)
|
|||
}
|
||||
};
|
||||
|
||||
sortBy(initialOrder || settings.sortorder);
|
||||
sortBy(store.get(storekey) || settings.order);
|
||||
|
||||
$label
|
||||
.append($ascending.clone()).append($descending.clone())
|
||||
|
@ -128,7 +141,5 @@ Module.define('sort', [jQuery, 'settings', 'core'], function ($, settings, core)
|
|||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
init();
|
||||
});
|
76
src/_h5ai/js/inc/ext/statusbar.js
Normal file
76
src/_h5ai/js/inc/ext/statusbar.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
|
||||
module.define('ext/statusbar', [jQuery, 'core/settings', 'core/format', 'core/event', 'core/entry'], function ($, allsettings, format, event, entry) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.statusbar),
|
||||
|
||||
template = '<span class="statusbar">' +
|
||||
'<span class="status default">' +
|
||||
'<span class="folderTotal"></span> <span class="l10n-folders">folders</span>' +
|
||||
'<span class="sep">·</span>' +
|
||||
'<span class="fileTotal"></span> <span class="l10n-files">files</span>' +
|
||||
'</span>' +
|
||||
'<span class="status dynamic"></span>' +
|
||||
'</span>',
|
||||
sepTemplate = '<span class="sep">·</span>',
|
||||
|
||||
$statusDynamic,
|
||||
$statusDefault,
|
||||
|
||||
update = function (html) {
|
||||
|
||||
if (html) {
|
||||
$statusDefault.hide();
|
||||
$statusDynamic.empty().append(html).show();
|
||||
} else {
|
||||
$statusDynamic.empty().hide();
|
||||
$statusDefault.show();
|
||||
}
|
||||
},
|
||||
|
||||
init = function (entry) {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $statusbar = $(template),
|
||||
$folderTotal = $statusbar.find('.folderTotal'),
|
||||
$fileTotal = $statusbar.find('.fileTotal');
|
||||
|
||||
$statusDefault = $statusbar.find('.status.default');
|
||||
$statusDynamic = $statusbar.find('.status.dynamic');
|
||||
|
||||
var stats = entry.getStats();
|
||||
$folderTotal.text(stats.folders);
|
||||
$fileTotal.text(stats.files);
|
||||
|
||||
update();
|
||||
|
||||
event.sub('statusbar', update);
|
||||
$('#bottombar > .center').append($statusbar);
|
||||
|
||||
|
||||
|
||||
event.sub('entry.mouseenter', function (entry) {
|
||||
|
||||
var $span = $('<span/>').append(entry.label).append(sepTemplate).append(format.formatDate(entry.time));
|
||||
|
||||
if (!entry.isFolder()) {
|
||||
$span.append(sepTemplate).append(format.formatSize(entry.size));
|
||||
}
|
||||
|
||||
update($span);
|
||||
});
|
||||
|
||||
event.sub('entry.mouseleave', function (entry) {
|
||||
|
||||
update();
|
||||
});
|
||||
};
|
||||
|
||||
init(entry);
|
||||
});
|
59
src/_h5ai/js/inc/ext/thumbnails.js
Normal file
59
src/_h5ai/js/inc/ext/thumbnails.js
Normal file
|
@ -0,0 +1,59 @@
|
|||
|
||||
module.define('ext/thumbnails', [jQuery, 'core/settings', 'core/resource', 'core/entry'], function ($, allsettings, resource, entry) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false,
|
||||
types: ["bmp", "gif", "ico", "image", "jpg", "png", "tiff"],
|
||||
delay: 1000
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.thumbnails),
|
||||
|
||||
requestThumb = function ($img, data) {
|
||||
|
||||
$.getJSON(resource.api(), data, function (json) {
|
||||
|
||||
if (json.code === 0) {
|
||||
$img.addClass('thumb').attr('src', json.absHref);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
checkEntry = function (entry) {
|
||||
|
||||
if (entry.$extended && $.inArray(entry.type, settings.types) >= 0) {
|
||||
|
||||
var $imgSmall = entry.$extended.find('.icon.small img');
|
||||
var $imgBig = entry.$extended.find('.icon.big img');
|
||||
|
||||
requestThumb($imgSmall, {
|
||||
action: 'thumbsrc',
|
||||
href: entry.absHref,
|
||||
width: 16,
|
||||
height: 16,
|
||||
mode: 'square'
|
||||
});
|
||||
requestThumb($imgBig, {
|
||||
action: 'thumbsrc',
|
||||
href: entry.absHref,
|
||||
width: 100,
|
||||
height: 48,
|
||||
mode: 'rational'
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
init = function (entry) {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
|
||||
_.each(entry.content, checkEntry);
|
||||
}, settings.delay);
|
||||
};
|
||||
|
||||
init(entry);
|
||||
});
|
27
src/_h5ai/js/inc/ext/title.js
Normal file
27
src/_h5ai/js/inc/ext/title.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
module.define('ext/title', [jQuery, 'core/settings', 'core/entry'], function ($, allsettings, entry) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.title),
|
||||
|
||||
init = function (entry) {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var labels = _.pluck(entry.getCrumb(), 'label'),
|
||||
title = labels.join(' > ');
|
||||
|
||||
if (labels.length > 1) {
|
||||
title = labels[labels.length - 1] + ' - ' + title;
|
||||
}
|
||||
|
||||
document.title = title;
|
||||
};
|
||||
|
||||
init(entry);
|
||||
});
|
227
src/_h5ai/js/inc/ext/tree.js
Normal file
227
src/_h5ai/js/inc/ext/tree.js
Normal file
|
@ -0,0 +1,227 @@
|
|||
|
||||
module.define('ext/tree', [jQuery, 'core/settings', 'core/resource', 'core/event', 'core/entry', 'core/parser'], function ($, allsettings, resource, event, entry, parser) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false,
|
||||
slide: true
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.tree),
|
||||
|
||||
template = '<div class="entry">' +
|
||||
'<span class="indicator none">' +
|
||||
'<img src="' + resource.image('tree') + '" />' +
|
||||
'</span>' +
|
||||
'<a>' +
|
||||
'<span class="icon"><img /></span>' +
|
||||
'<span class="label"></span>' +
|
||||
'</a>' +
|
||||
'</span>',
|
||||
statusHintTemplate = '<span class="hint"></span>',
|
||||
|
||||
// updates the tree for this single entry
|
||||
update = function (entry) {
|
||||
|
||||
var $html = $(template),
|
||||
$indicator = $html.find('.indicator'),
|
||||
$a = $html.find('a'),
|
||||
$img = $html.find('.icon img'),
|
||||
$label = $html.find('.label');
|
||||
|
||||
$html
|
||||
.addClass(entry.isFolder() ? 'folder' : 'file')
|
||||
.data('entry', entry)
|
||||
.data('status', entry.status);
|
||||
|
||||
$a.attr('href', entry.absHref);
|
||||
$img.attr('src', resource.icon(entry.type));
|
||||
$label.text(entry.label);
|
||||
|
||||
if (entry.isFolder()) {
|
||||
|
||||
var subfolders = entry.getSubfolders();
|
||||
|
||||
// indicator
|
||||
if (!entry.status || (entry.status === 'h5ai' && !entry.isContentFetched) || subfolders.length) {
|
||||
|
||||
$indicator.removeClass('none');
|
||||
|
||||
if (!entry.status || (entry.status === 'h5ai' && !entry.isContentFetched)) {
|
||||
$indicator.addClass('unknown');
|
||||
} else if (entry.isContentVisible) {
|
||||
$indicator.addClass('open');
|
||||
} else {
|
||||
$indicator.addClass('close');
|
||||
}
|
||||
}
|
||||
|
||||
// is it the domain?
|
||||
if (entry.isDomain()) {
|
||||
$html.addClass('domain');
|
||||
$img.attr('src', resource.icon('folder-home'));
|
||||
}
|
||||
|
||||
// is it the current folder?
|
||||
if (entry.isCurrentFolder()) {
|
||||
$html.addClass('current');
|
||||
$img.attr('src', resource.icon('folder-open'));
|
||||
}
|
||||
|
||||
// does it have subfolders?
|
||||
if (subfolders.length) {
|
||||
var $ul = $('<ul class="content" />').appendTo($html);
|
||||
_.each(subfolders, function (e) {
|
||||
$('<li />').append(update(e)).appendTo($ul);
|
||||
});
|
||||
if (!entry.isContentVisible) {
|
||||
$ul.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// reflect folder status
|
||||
if (_.isNumber(entry.status)) {
|
||||
if (entry.status === 200) {
|
||||
$img.attr('src', resource.icon('folder-page'));
|
||||
} else {
|
||||
$html.addClass('error');
|
||||
$a.append($(statusHintTemplate).text(entry.status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (entry.$tree) {
|
||||
entry.$tree.replaceWith($html);
|
||||
}
|
||||
entry.$tree = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
|
||||
createOnIndicatorClick = function (parser) {
|
||||
|
||||
var $tree = $('#tree'),
|
||||
tree = $tree.get(0),
|
||||
slide = function (entry, $indicator, $content, down) {
|
||||
|
||||
entry.isContentVisible = down;
|
||||
$indicator.removeClass('open close').addClass(down ? 'open' : 'close');
|
||||
tree.updateScrollbar(true);
|
||||
$content[down ? 'slideDown' : 'slideUp'](function () {
|
||||
|
||||
tree.updateScrollbar();
|
||||
});
|
||||
};
|
||||
|
||||
return function () {
|
||||
|
||||
var $indicator = $(this),
|
||||
$entry = $indicator.closest('.entry'),
|
||||
entry = $entry.data('entry'),
|
||||
$content = $entry.find('> ul.content');
|
||||
|
||||
if ($indicator.hasClass('unknown')) {
|
||||
|
||||
entry.fetchContent(parser, function (entry) {
|
||||
|
||||
entry.isContentVisible = false;
|
||||
|
||||
var $entry = update(entry),
|
||||
$indicator = $entry.find('> .indicator'),
|
||||
$content = $entry.find('> ul.content');
|
||||
|
||||
if (!$indicator.hasClass('none')) {
|
||||
slide(entry, $indicator, $content, true);
|
||||
}
|
||||
});
|
||||
|
||||
} else if ($indicator.hasClass('open')) {
|
||||
|
||||
slide(entry, $indicator, $content, false);
|
||||
|
||||
} else if ($indicator.hasClass('close')) {
|
||||
|
||||
slide(entry, $indicator, $content, true);
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
shiftTree = function (forceVisible, dontAnimate) {
|
||||
|
||||
var $tree = $("#tree"),
|
||||
$extended = $("#extended"),
|
||||
left = ((settings.slide && $tree.outerWidth() < $extended.offset().left) || forceVisible || !$extended.is(':visible')) ? 0 : 18 - $tree.outerWidth();
|
||||
|
||||
if (dontAnimate) {
|
||||
$tree.stop().css({ left: left });
|
||||
} else {
|
||||
$tree.stop().animate({ left: left });
|
||||
}
|
||||
},
|
||||
|
||||
fetchTree = function (entry, parser, callback) {
|
||||
|
||||
entry.isContentVisible = true;
|
||||
entry.fetchContent(parser, function (entry) {
|
||||
|
||||
if (entry.parent) {
|
||||
fetchTree(entry.parent, parser, callback);
|
||||
} else {
|
||||
callback(entry);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
adjustSpacing = function () {
|
||||
|
||||
var $tree = $('#tree'),
|
||||
tree = $tree[0],
|
||||
winHeight = $(window).height(),
|
||||
navHeight = $('#topbar').outerHeight(),
|
||||
footerHeight = $('#bottombar').outerHeight();
|
||||
|
||||
$tree.css({
|
||||
top: navHeight,
|
||||
height: winHeight - navHeight - footerHeight - 16
|
||||
});
|
||||
|
||||
if (tree.updateScrollbar) {
|
||||
tree.updateScrollbar();
|
||||
}
|
||||
},
|
||||
|
||||
// creates the complete tree from entry down to the root
|
||||
init = function (entry, parser) {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $tree = $('<div id="tree" />').appendTo($('body'));
|
||||
|
||||
fetchTree(entry, parser, function (root) {
|
||||
|
||||
$tree
|
||||
.append(update(root))
|
||||
.scrollpanel()
|
||||
.show();
|
||||
|
||||
adjustSpacing();
|
||||
shiftTree(false, true);
|
||||
setTimeout(function () { $tree.get(0).updateScrollbar(); }, 1);
|
||||
});
|
||||
|
||||
$tree
|
||||
.on('click', '.indicator', createOnIndicatorClick(parser))
|
||||
.on('mouseenter', function () { shiftTree(true); })
|
||||
.on('mouseleave', function () { shiftTree(); });
|
||||
|
||||
event.sub('ready', adjustSpacing);
|
||||
$(window).on('resize', function () {
|
||||
adjustSpacing();
|
||||
shiftTree();
|
||||
});
|
||||
};
|
||||
|
||||
init(entry, parser);
|
||||
});
|
133
src/_h5ai/js/inc/ext/zipped-download.js
Normal file
133
src/_h5ai/js/inc/ext/zipped-download.js
Normal file
|
@ -0,0 +1,133 @@
|
|||
|
||||
module.define('ext/zipped-download', [jQuery, 'core/settings', 'core/resource', 'core/event'], function ($, allsettings, resource, event) {
|
||||
|
||||
var defaults = {
|
||||
enabled: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings['zipped-download']),
|
||||
|
||||
downloadBtnTemplate = '<li id="download">' +
|
||||
'<a href="#">' +
|
||||
'<img src="' + resource.image('download') + '" alt="download" />' +
|
||||
'<span class="l10n-download">download</span>' +
|
||||
'</a>' +
|
||||
'</li>',
|
||||
authTemplate = '<div id="download-auth">' +
|
||||
'<input id="download-auth-user" type="text" value="" placeholder="user" />' +
|
||||
'<input id="download-auth-password" type="text" value="" placeholder="password" />' +
|
||||
'</div>',
|
||||
|
||||
selectedHrefsStr = '',
|
||||
$download, $img, $downloadAuth, $downloadUser, $downloadPassword,
|
||||
|
||||
failed = function () {
|
||||
|
||||
$download.addClass('failed');
|
||||
setTimeout(function () {
|
||||
$download.removeClass('failed');
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
handleResponse = function (response) {
|
||||
|
||||
$download.removeClass('current');
|
||||
$img.attr('src', resource.image('download'));
|
||||
|
||||
if (response) {
|
||||
if (response.status === 'ok') {
|
||||
setTimeout(function () { // wait here so the img above can be updated in time
|
||||
|
||||
window.location = resource.api() + '?action=getzip&id=' + response.id;
|
||||
}, 200);
|
||||
} else {
|
||||
if (response.code === 401) {
|
||||
$downloadAuth
|
||||
.css({
|
||||
left: $download.offset().left,
|
||||
top: $download.offset().top + $download.outerHeight()
|
||||
})
|
||||
.show();
|
||||
$downloadUser.focus();
|
||||
}
|
||||
failed();
|
||||
}
|
||||
} else {
|
||||
failed();
|
||||
}
|
||||
},
|
||||
|
||||
requestZipping = function (hrefsStr) {
|
||||
|
||||
$download.addClass('current');
|
||||
$img.attr('src', resource.image('loading.gif', true));
|
||||
$.ajax({
|
||||
url: resource.api(),
|
||||
data: {
|
||||
action: 'zip',
|
||||
hrefs: hrefsStr
|
||||
},
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: function (xhr) {
|
||||
|
||||
var user = $downloadUser.val(),
|
||||
password = $downloadPassword.val();
|
||||
|
||||
if (user) {
|
||||
xhr.setRequestHeader('Authorization', 'Basic ' + Base64.encode(user + ':' + password));
|
||||
}
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
handleResponse(response);
|
||||
},
|
||||
error: function () {
|
||||
|
||||
handleResponse();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
onSelection = function (entries) {
|
||||
|
||||
var $downloadBtn = $('#download');
|
||||
|
||||
selectedHrefsStr = '';
|
||||
if (entries.length) {
|
||||
selectedHrefsStr = _.map(entries, function (entry) {
|
||||
|
||||
return entry.absHref;
|
||||
}).join(':');
|
||||
$downloadBtn.show();
|
||||
} else {
|
||||
$downloadBtn.hide();
|
||||
$downloadAuth.hide();
|
||||
}
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
if (!settings.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
$download = $(downloadBtnTemplate)
|
||||
.appendTo($('#navbar'))
|
||||
.find('a').on('click', function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$downloadAuth.hide();
|
||||
requestZipping(selectedHrefsStr);
|
||||
});
|
||||
$img = $download.find('img');
|
||||
|
||||
$downloadAuth = $(authTemplate).appendTo($('body'));
|
||||
$downloadUser = $downloadAuth.find('#download-auth-user');
|
||||
$downloadPassword = $downloadAuth.find('#download-auth-password');
|
||||
|
||||
event.sub('selection', onSelection);
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
|
@ -1,130 +0,0 @@
|
|||
|
||||
Module.define('extended', [jQuery, 'settings', 'conhtml', 'util', 'core'], function ($, settings, conhtml, util, core) {
|
||||
|
||||
var initBreadcrumb = function () {
|
||||
|
||||
var $ul = $("body > nav ul"),
|
||||
pathname = "/",
|
||||
path = conhtml.getPath(pathname),
|
||||
pathnameParts = document.location.pathname.split("/"),
|
||||
lastPart = "",
|
||||
title = document.domain;
|
||||
|
||||
$ul.append(conhtml.updateCrumbHtml(path));
|
||||
|
||||
$.each(pathnameParts, function (idx, part) {
|
||||
if (part !== "") {
|
||||
pathname += part + "/";
|
||||
$ul.append(conhtml.updateCrumbHtml(conhtml.getPath(pathname)));
|
||||
lastPart = part + " - ";
|
||||
title += " > " + part;
|
||||
}
|
||||
});
|
||||
|
||||
document.title = util.checkedDecodeUri(lastPart + title);
|
||||
},
|
||||
initExtendedView = function () {
|
||||
|
||||
var $ul, $li;
|
||||
|
||||
$ul = $("<ul/>");
|
||||
$li = $("<li class='header' />")
|
||||
.appendTo($ul)
|
||||
.append($("<a class='icon'></a>"))
|
||||
.append($("<a class='label' href='#'><span class='l10n-name'></span></a>"))
|
||||
.append($("<a class='date' href='#'><span class='l10n-lastModified'></span></a>"))
|
||||
.append($("<a class='size' href='#'><span class='l10n-size'></span></a>"));
|
||||
|
||||
// entries
|
||||
$("#table td").closest("tr").each(function () {
|
||||
var path = conhtml.getPath(document.location.pathname, this);
|
||||
$ul.append(conhtml.updateExtendedHtml(path));
|
||||
});
|
||||
|
||||
$("#extended").append($ul);
|
||||
|
||||
// empty
|
||||
if ($ul.children(".entry:not(.folder-parent)").size() === 0) {
|
||||
$("#extended").append($("<div class='empty l10n-empty'>empty</div>"));
|
||||
}
|
||||
|
||||
// no match
|
||||
$("#extended").append($("<div class='no-match l10n-noMatch'>no match</div>"));
|
||||
},
|
||||
customize = function () {
|
||||
|
||||
if (settings.customHeader) {
|
||||
$.ajax({
|
||||
url: settings.customHeader,
|
||||
dataType: "html",
|
||||
success: function (data) {
|
||||
$("#content > header").append($(data)).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (settings.customFooter) {
|
||||
$.ajax({
|
||||
url: settings.customFooter,
|
||||
dataType: "html",
|
||||
success: function (data) {
|
||||
$("#content > footer").prepend($(data)).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
fetchPath = function (pathname, callback) {
|
||||
|
||||
conhtml.fetchStatusAndContent(pathname, false, function (status, content) {
|
||||
|
||||
var path = conhtml.getPath(pathname);
|
||||
|
||||
path.status = status;
|
||||
path.content = content;
|
||||
callback(path);
|
||||
});
|
||||
},
|
||||
fetchTree = function (pathname, callback, childPath) {
|
||||
|
||||
fetchPath(pathname, function (path) {
|
||||
|
||||
var parent = util.splitPath(pathname).parent;
|
||||
|
||||
path.treeOpen = true;
|
||||
if (childPath) {
|
||||
path.content[childPath.absHref] = childPath;
|
||||
}
|
||||
if (parent === null) {
|
||||
callback(path);
|
||||
} else {
|
||||
fetchTree(parent, callback, path);
|
||||
}
|
||||
});
|
||||
},
|
||||
populateTree = function () {
|
||||
|
||||
fetchTree(document.location.pathname, function (path) {
|
||||
$("#tree")
|
||||
.append(conhtml.updateTreeHtml(path))
|
||||
.scrollpanel()
|
||||
.show();
|
||||
core.shiftTree(false, true);
|
||||
core.linkHoverStates();
|
||||
setTimeout(function () { $("#tree").get(0).updateScrollbar(); }, 1);
|
||||
});
|
||||
},
|
||||
init = function () {
|
||||
|
||||
initBreadcrumb();
|
||||
initExtendedView();
|
||||
customize();
|
||||
conhtml.updatePaths();
|
||||
if (settings.showTree) {
|
||||
populateTree();
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
});
|
|
@ -1,106 +0,0 @@
|
|||
|
||||
Module.define('finder', [jQuery, 'settings', 'util', 'core'], function ($, settings, util, core) {
|
||||
|
||||
var filter = function (re) {
|
||||
|
||||
var match = [],
|
||||
noMatch = [];
|
||||
|
||||
if (re) {
|
||||
$('#extended .entry').each(function () {
|
||||
|
||||
var label = $(this).find('.label').text();
|
||||
|
||||
if (label.match(re)) {
|
||||
match.push(this);
|
||||
} else {
|
||||
noMatch.push(this);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
match = $('#extended .entry');
|
||||
}
|
||||
|
||||
if ($(match).length) {
|
||||
$('#extended .no-match').hide();
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
|
||||
$('#extended .no-match').show();
|
||||
}, 200);
|
||||
}
|
||||
$(match).fadeIn(200);
|
||||
$(noMatch).fadeOut(200);
|
||||
},
|
||||
checkState = function (focus) {
|
||||
|
||||
var $filter = $('#filter'),
|
||||
$input = $filter.find('input'),
|
||||
val = $input.val();
|
||||
|
||||
if (val || focus) {
|
||||
$filter.addClass('current');
|
||||
} else {
|
||||
$filter.removeClass('current');
|
||||
}
|
||||
core.hash({filter: val});
|
||||
},
|
||||
parseFilterSequence = function (sequence) {
|
||||
|
||||
if (sequence.substr(0,3) === 're:') {
|
||||
return new RegExp(sequence.substr(3));
|
||||
}
|
||||
|
||||
sequence = $.map($.trim(sequence).split(/\s+/), function (part) {
|
||||
|
||||
return util.reEscape(part);
|
||||
}).join('|');
|
||||
return new RegExp(sequence);
|
||||
},
|
||||
init = function () {
|
||||
|
||||
if (settings.showFilter) {
|
||||
$('<li id="filter"><span class="element"><img alt="filter" /><input type="text" value="" placeholder="filter" /></span></li>')
|
||||
.on('click', function () {
|
||||
|
||||
var $input = $(this).find('input');
|
||||
$input.focus();
|
||||
})
|
||||
.find('img').attr('src', core.image('filter')).end()
|
||||
.find('input')
|
||||
.on('focus', function () {
|
||||
|
||||
checkState(true);
|
||||
})
|
||||
.on('blur', function () {
|
||||
|
||||
checkState(false);
|
||||
})
|
||||
.on('keyup', function () {
|
||||
|
||||
var $input = $(this),
|
||||
val = $input.val();
|
||||
|
||||
if (val) {
|
||||
filter(parseFilterSequence(val));
|
||||
} else {
|
||||
filter();
|
||||
}
|
||||
checkState($input.is(':focus'));
|
||||
})
|
||||
.end()
|
||||
.appendTo($('#navbar'));
|
||||
|
||||
var initialFilter = core.hash('filter');
|
||||
if (initialFilter) {
|
||||
$('#filter input').val(initialFilter);
|
||||
checkState(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
init: init,
|
||||
filter: filter
|
||||
};
|
||||
});
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
Module.define('splash', [jQuery, 'core'], function ($, core) {
|
||||
module.define('h5ai-info', [jQuery, 'core/resource'], function ($, resource) {
|
||||
|
||||
var setCheckResult = function (id, result) {
|
||||
|
||||
|
@ -11,16 +11,19 @@ Module.define('splash', [jQuery, 'core'], function ($, core) {
|
|||
$ele.addClass('test-failed').text('no');
|
||||
}
|
||||
},
|
||||
|
||||
handleChecksResponse = function (response) {
|
||||
|
||||
setCheckResult('#test-php', response && response.php);
|
||||
setCheckResult('#test-zips', response && response.zips);
|
||||
setCheckResult('#test-thumbs', response && response.thumbs);
|
||||
_.each(['php', 'cache', 'thumbs', 'temp', 'zips'], function (test) {
|
||||
|
||||
setCheckResult('#test-' + test, response && response[test]);
|
||||
})
|
||||
},
|
||||
|
||||
checks = function () {
|
||||
|
||||
$.ajax({
|
||||
url: core.api(),
|
||||
url: resource.api(),
|
||||
data: {
|
||||
action: 'checks'
|
||||
},
|
||||
|
@ -36,12 +39,11 @@ Module.define('splash', [jQuery, 'core'], function ($, core) {
|
|||
}
|
||||
});
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
checks();
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
init();
|
||||
});
|
21
src/_h5ai/js/inc/h5ai-main.js
Normal file
21
src/_h5ai/js/inc/h5ai-main.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
|
||||
module.define('h5ai-main', [jQuery, 'core/event'], function ($, event) {
|
||||
|
||||
|
||||
event.pub('beforeView');
|
||||
|
||||
module.require('view/extended');
|
||||
module.require('view/viewmode');
|
||||
module.require('view/spacing');
|
||||
|
||||
$('#h5ai-reference').append(module.require('core/parser').id === 'apache-autoindex' ? ' (js)' : ' (php)');
|
||||
|
||||
event.pub('beforeExt');
|
||||
|
||||
_.each(module.getIds(/^ext\/.+/), function (id) {
|
||||
|
||||
module.require(id);
|
||||
});
|
||||
|
||||
event.pub('ready');
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
|
||||
Module.define('h5ai', [jQuery, 'core', 'extended', 'localize', 'sort', 'finder', 'zip', 'context', 'splash'], function ($, core, extended, localize, sort, finder, zip, context, splash) {
|
||||
|
||||
var h5ai = {};
|
||||
|
||||
h5ai.init = function () {
|
||||
|
||||
var $html = $('html');
|
||||
|
||||
h5ai.isJs = $html.hasClass('h5ai-js');
|
||||
h5ai.isPhp = $html.hasClass('h5ai-php');
|
||||
h5ai.isSplash = $html.hasClass('h5ai-splash');
|
||||
|
||||
if (h5ai.isJs || h5ai.isPhp) {
|
||||
if (h5ai.isJs) {
|
||||
extended.init();
|
||||
}
|
||||
|
||||
core.init();
|
||||
localize.init();
|
||||
sort.init();
|
||||
finder.init();
|
||||
zip.init();
|
||||
context.init();
|
||||
|
||||
if (h5ai.isPhp) {
|
||||
$('#tree').scrollpanel();
|
||||
core.shiftTree(false, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (h5ai.isSplash) {
|
||||
splash.init();
|
||||
}
|
||||
};
|
||||
|
||||
return h5ai;
|
||||
});
|
84
src/_h5ai/js/inc/lib/jquery.mousewheel-3.0.6.js
Normal file
84
src/_h5ai/js/inc/lib/jquery.mousewheel-3.0.6.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||
*
|
||||
* Version: 3.0.6
|
||||
*
|
||||
* Requires: 1.2.2+
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var types = ['DOMMouseScroll', 'mousewheel'];
|
||||
|
||||
if ($.event.fixHooks) {
|
||||
for ( var i=types.length; i; ) {
|
||||
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
|
||||
}
|
||||
}
|
||||
|
||||
$.event.special.mousewheel = {
|
||||
setup: function() {
|
||||
if ( this.addEventListener ) {
|
||||
for ( var i=types.length; i; ) {
|
||||
this.addEventListener( types[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = handler;
|
||||
}
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if ( this.removeEventListener ) {
|
||||
for ( var i=types.length; i; ) {
|
||||
this.removeEventListener( types[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
mousewheel: function(fn) {
|
||||
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
|
||||
},
|
||||
|
||||
unmousewheel: function(fn) {
|
||||
return this.unbind("mousewheel", fn);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handler(event) {
|
||||
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
|
||||
event = $.event.fix(orgEvent);
|
||||
event.type = "mousewheel";
|
||||
|
||||
// Old school scrollwheel delta
|
||||
if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta/120; }
|
||||
if ( orgEvent.detail ) { delta = -orgEvent.detail/3; }
|
||||
|
||||
// New school multidimensional scroll (touchpads) deltas
|
||||
deltaY = delta;
|
||||
|
||||
// Gecko
|
||||
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||
deltaY = 0;
|
||||
deltaX = -1*delta;
|
||||
}
|
||||
|
||||
// Webkit
|
||||
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
|
||||
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
|
||||
|
||||
// Add event and delta to the front of the arguments
|
||||
args.unshift(event, delta, deltaX, deltaY);
|
||||
|
||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||
}
|
||||
|
||||
})(jQuery);
|
|
@ -1,84 +0,0 @@
|
|||
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
||||
* Licensed under the MIT License (LICENSE.txt).
|
||||
*
|
||||
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
||||
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
||||
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
||||
*
|
||||
* Version: 3.0.5
|
||||
*
|
||||
* Requires: 1.2.2+
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
|
||||
var types = ['DOMMouseScroll', 'mousewheel'];
|
||||
|
||||
if ($.event.fixHooks) {
|
||||
for ( var i=types.length; i; ) {
|
||||
$.event.fixHooks[ types[--i] ] = $.event.mouseHooks;
|
||||
}
|
||||
}
|
||||
|
||||
$.event.special.mousewheel = {
|
||||
setup: function() {
|
||||
if ( this.addEventListener ) {
|
||||
for ( var i=types.length; i; ) {
|
||||
this.addEventListener( types[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = handler;
|
||||
}
|
||||
},
|
||||
|
||||
teardown: function() {
|
||||
if ( this.removeEventListener ) {
|
||||
for ( var i=types.length; i; ) {
|
||||
this.removeEventListener( types[--i], handler, false );
|
||||
}
|
||||
} else {
|
||||
this.onmousewheel = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
mousewheel: function(fn) {
|
||||
return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
|
||||
},
|
||||
|
||||
unmousewheel: function(fn) {
|
||||
return this.unbind("mousewheel", fn);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function handler(event) {
|
||||
var orgEvent = event || window.event, args = [].slice.call( arguments, 1 ), delta = 0, returnValue = true, deltaX = 0, deltaY = 0;
|
||||
event = $.event.fix(orgEvent);
|
||||
event.type = "mousewheel";
|
||||
|
||||
// Old school scrollwheel delta
|
||||
if ( event.wheelDelta ) { delta = event.wheelDelta/120; }
|
||||
if ( event.detail ) { delta = -event.detail/3; }
|
||||
|
||||
// New school multidimensional scroll (touchpads) deltas
|
||||
deltaY = delta;
|
||||
|
||||
// Gecko
|
||||
if ( orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS ) {
|
||||
deltaY = 0;
|
||||
deltaX = -1*delta;
|
||||
}
|
||||
|
||||
// Webkit
|
||||
if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY/120; }
|
||||
if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = -1*orgEvent.wheelDeltaX/120; }
|
||||
|
||||
// Add event and delta to the front of the arguments
|
||||
args.unshift(event, delta, deltaX, deltaY);
|
||||
|
||||
return ($.event.dispatch || $.event.handle).apply(this, args);
|
||||
}
|
||||
|
||||
})(jQuery);
|
196
src/_h5ai/js/inc/lib/module.js
Normal file
196
src/_h5ai/js/inc/lib/module.js
Normal file
|
@ -0,0 +1,196 @@
|
|||
/*!
|
||||
* module.js
|
||||
* author: Lars Jung
|
||||
* license: MIT
|
||||
*/
|
||||
|
||||
(function (global, name) {
|
||||
'use strict';
|
||||
|
||||
var self = {},
|
||||
previous = global[name],
|
||||
|
||||
noConflict = function () {
|
||||
|
||||
if (global[name] === self) {
|
||||
global[name] = previous;
|
||||
}
|
||||
return self;
|
||||
},
|
||||
|
||||
err = function (message) {
|
||||
|
||||
throw name + ' exception: ' + message;
|
||||
},
|
||||
|
||||
definitions = {},
|
||||
modules = {},
|
||||
|
||||
findDepsUnsafe = function (ids) {
|
||||
|
||||
var self = this;
|
||||
var deps = [];
|
||||
|
||||
if (_.isString(ids)) {
|
||||
|
||||
var def = definitions[ids];
|
||||
if (def) {
|
||||
_.each(def.deps, function (id) {
|
||||
|
||||
deps = deps.concat(findDepsUnsafe(id));
|
||||
});
|
||||
deps.push(def.id);
|
||||
} else {
|
||||
deps.push(ids);
|
||||
}
|
||||
} else if (_.isArray(ids)) {
|
||||
|
||||
_.each(ids, function (id) {
|
||||
|
||||
deps = deps.concat(findDepsUnsafe(id));
|
||||
});
|
||||
}
|
||||
|
||||
return _.uniq(deps);
|
||||
},
|
||||
|
||||
findDeps = function (ids) {
|
||||
|
||||
if (ids) {
|
||||
try {
|
||||
return findDepsUnsafe(ids);
|
||||
} catch (e) {
|
||||
err('cyclic dependencies for ids "' + ids + '"');
|
||||
}
|
||||
} else {
|
||||
var res = {};
|
||||
_.each(definitions, function (def, id) {
|
||||
|
||||
res[id] = findDeps(id);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
},
|
||||
|
||||
log = function (showInvDeps) {
|
||||
|
||||
var allDeps = findDeps(),
|
||||
allInvDeps = {},
|
||||
out = '';
|
||||
|
||||
if (!showInvDeps) {
|
||||
_.each(allDeps, function (deps, id) {
|
||||
|
||||
deps.pop();
|
||||
out += (_.has(modules, id) ? '* ' : ' ') + id + ' -> [ ' + deps.join(', ') + ' ]\n';
|
||||
});
|
||||
} else {
|
||||
_.each(definitions, function (def) {
|
||||
|
||||
var invDeps = [];
|
||||
_.each(allDeps, function (depId, id) {
|
||||
|
||||
if (_.inArray(def.id, depId) >= 0) {
|
||||
invDeps.push(id);
|
||||
}
|
||||
});
|
||||
allInvDeps[def.id] = invDeps;
|
||||
});
|
||||
|
||||
_.each(allInvDeps, function (invDeps, id) {
|
||||
|
||||
invDeps.shift();
|
||||
out += (_.has(modules, id) ? '* ' : ' ') + id + ' <- [ ' + invDeps.join(', ') + ' ]\n';
|
||||
});
|
||||
}
|
||||
|
||||
return out;
|
||||
},
|
||||
|
||||
define = function (id, deps, fn) {
|
||||
|
||||
if (_.isFunction(deps)) {
|
||||
fn = deps;
|
||||
deps = [];
|
||||
}
|
||||
if (!_.isString(id)) {
|
||||
err('id must be a string "' + id + '"');
|
||||
}
|
||||
if (!_.isArray(deps)) {
|
||||
err('dependencies must be an array "' + deps + '"');
|
||||
}
|
||||
if (!_.isFunction(fn)) {
|
||||
err('constructor must be a function "' + fn + '"');
|
||||
}
|
||||
if (definitions[id]) {
|
||||
err('id already defined "' + id + '"');
|
||||
}
|
||||
|
||||
definitions[id] = {
|
||||
id: id,
|
||||
deps: deps,
|
||||
fn: fn
|
||||
};
|
||||
},
|
||||
|
||||
getIds = function (regexp) {
|
||||
|
||||
var ids = _.map(definitions, function (def) {
|
||||
|
||||
return def.id;
|
||||
});
|
||||
|
||||
if (!_.isRegExp(regexp)) {
|
||||
return ids;
|
||||
}
|
||||
|
||||
return _.filter(ids, function (id) {
|
||||
|
||||
return regexp.test(id);
|
||||
});
|
||||
},
|
||||
|
||||
isDefined = function (id) {
|
||||
|
||||
return _.isString(id) ? !!definitions[id] : !!id;
|
||||
},
|
||||
|
||||
require = function (id) {
|
||||
|
||||
if (!_.isString(id)) {
|
||||
return id;
|
||||
}
|
||||
|
||||
if (_.has(modules, id)) {
|
||||
return modules[id];
|
||||
}
|
||||
|
||||
var def = definitions[id];
|
||||
if (!def) {
|
||||
err('id not defined "' + id + '"');
|
||||
}
|
||||
|
||||
var deps = _.map(def.deps, function (depId) {
|
||||
|
||||
return require(depId);
|
||||
});
|
||||
|
||||
var obj = def.fn.apply(this, deps);
|
||||
modules[id] = obj;
|
||||
return obj;
|
||||
};
|
||||
|
||||
if (!_) {
|
||||
err(name + ' depends on underscore');
|
||||
}
|
||||
|
||||
self.noConflict = noConflict;
|
||||
self.log = log;
|
||||
self.define = define;
|
||||
self.require = require;
|
||||
self.getIds = getIds;
|
||||
self.isDefined = isDefined;
|
||||
|
||||
global[name] = self;
|
||||
|
||||
}(this, 'module'));
|
|
@ -1,36 +1,48 @@
|
|||
|
||||
(function () {
|
||||
'use strict';
|
||||
/*jslint browser: true, confusion: true, regexp: true, vars: true, white: true */
|
||||
/*global Modernizr, jQuery, amplify, Base64, H5AI_CONFIG */
|
||||
(function ($) {
|
||||
'use strict';
|
||||
/*jshint browser: true */
|
||||
/*global _, amplify, Base64, H5AI_CONFIG, jQuery, Modernizr, module, moment */
|
||||
|
||||
// @include "module.js"
|
||||
// @include "core/entry.js"
|
||||
// @include "core/event.js"
|
||||
// @include "core/format.js"
|
||||
// @include "core/parser.js"
|
||||
// @include "core/resource.js"
|
||||
// @include "core/settings.js"
|
||||
// @include "core/store.js"
|
||||
|
||||
// @include "settings.js"
|
||||
// @include "model/entry.js"
|
||||
|
||||
// @include "util.js"
|
||||
// @include "core.js"
|
||||
// @include "localize.js"
|
||||
// @include "sort.js"
|
||||
// @include "zip.js"
|
||||
// @include "finder.js"
|
||||
// @include "context.js"
|
||||
// @include "parser/apache-autoindex.js"
|
||||
// @include "parser/generic-json.js"
|
||||
|
||||
// @include "path.js"
|
||||
// @include "connector.js"
|
||||
// @include "html.js"
|
||||
// @include "extended.js"
|
||||
// @include "view/extended.js"
|
||||
// @include "view/spacing.js"
|
||||
// @include "view/viewmode.js"
|
||||
|
||||
// @include "splash.js"
|
||||
// @include "ext/crumb.js"
|
||||
// @include "ext/custom.js"
|
||||
// @include "ext/filter.js"
|
||||
// @include "ext/folderstatus.js"
|
||||
// @include "ext/l10n.js"
|
||||
// @include "ext/link-hover-states.js"
|
||||
// @include "ext/qrcode.js"
|
||||
// @include "ext/select.js"
|
||||
// @include "ext/sort.js"
|
||||
// @include "ext/statusbar.js"
|
||||
// @include "ext/thumbnails.js"
|
||||
// @include "ext/title.js"
|
||||
// @include "ext/tree.js"
|
||||
// @include "ext/zipped-download.js"
|
||||
|
||||
// @include "h5ai.js"
|
||||
// @include "h5ai-info.js"
|
||||
// @include "h5ai-main.js"
|
||||
|
||||
|
||||
jQuery(function () {
|
||||
$(function () {
|
||||
|
||||
var h5ai = Module.require('h5ai');
|
||||
|
||||
h5ai.init();
|
||||
module.require($('body').attr('id'));
|
||||
});
|
||||
|
||||
}());
|
||||
}(jQuery));
|
||||
|
|
282
src/_h5ai/js/inc/model/entry.js
Normal file
282
src/_h5ai/js/inc/model/entry.js
Normal file
|
@ -0,0 +1,282 @@
|
|||
|
||||
module.define('model/entry', [jQuery, 'core/types'], function ($, types) {
|
||||
|
||||
var domain = document.domain,
|
||||
location = document.location.pathname,
|
||||
|
||||
|
||||
// utils
|
||||
|
||||
reEndsWithSlash = /\/$/,
|
||||
|
||||
pathEndsWithSlash = function (sequence) {
|
||||
|
||||
return reEndsWithSlash.test(sequence);
|
||||
},
|
||||
|
||||
createLabel = function (sequence) {
|
||||
|
||||
if (sequence.length > 1 && reEndsWithSlash.test(sequence)) {
|
||||
sequence = sequence.slice(0, -1);
|
||||
}
|
||||
try {
|
||||
sequence = decodeURI(sequence);
|
||||
} catch (err) {}
|
||||
return sequence;
|
||||
},
|
||||
|
||||
|
||||
reSplitPath = /^\/([^\/]+\/?)$/,
|
||||
reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/,
|
||||
|
||||
splitPath = function (sequence) {
|
||||
|
||||
var match;
|
||||
|
||||
sequence = sequence.replace(/\/+/g, '/');
|
||||
if (sequence === '/') {
|
||||
return {
|
||||
parent: null,
|
||||
parentname: null,
|
||||
name: '/'
|
||||
};
|
||||
}
|
||||
match = reSplitPath2.exec(sequence);
|
||||
if (match) {
|
||||
return {
|
||||
parent: match[1],
|
||||
parentname: match[2],
|
||||
name: match[3]
|
||||
};
|
||||
}
|
||||
match = reSplitPath.exec(sequence);
|
||||
if (match) {
|
||||
return {
|
||||
parent: '/',
|
||||
parentname: '/',
|
||||
name: match[1]
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
extToFileType = (function (types) {
|
||||
var map = {};
|
||||
$.each(types, function (type, exts) {
|
||||
$.each(exts, function (idx, ext) {
|
||||
map[ext] = type;
|
||||
});
|
||||
});
|
||||
return map;
|
||||
}(types)),
|
||||
|
||||
getFileType = function (sequence) {
|
||||
|
||||
if (pathEndsWithSlash(sequence)) {
|
||||
return 'folder';
|
||||
}
|
||||
|
||||
var dotidx = sequence.lastIndexOf('.'),
|
||||
ext = dotidx >= 0 ? sequence.substr(dotidx) : sequence;
|
||||
|
||||
return extToFileType[ext.toLowerCase()] || 'unknown';
|
||||
},
|
||||
|
||||
|
||||
reContentType = /^text\/html;h5ai=/,
|
||||
|
||||
ajaxRequest = function (self, parser, callback) {
|
||||
|
||||
$.ajax({
|
||||
url: self.absHref,
|
||||
type: parser ? 'GET' : 'HEAD',
|
||||
complete: function (xhr) {
|
||||
|
||||
if (xhr.status === 200 && reContentType.test(xhr.getResponseHeader('Content-Type'))) {
|
||||
self.status = 'h5ai';
|
||||
if (parser) {
|
||||
parser.parse(self.absHref, xhr.responseText);
|
||||
}
|
||||
} else {
|
||||
self.status = xhr.status;
|
||||
}
|
||||
|
||||
callback(self);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
|
||||
|
||||
// Entry
|
||||
|
||||
cache = {},
|
||||
|
||||
Entry = function (absHref) {
|
||||
|
||||
var split = splitPath(absHref);
|
||||
|
||||
cache[absHref] = this;
|
||||
|
||||
this.absHref = absHref;
|
||||
this.type = getFileType(absHref);
|
||||
this.label = createLabel(absHref === '/' ? domain : split.name);
|
||||
this.time = null;
|
||||
this.size = null;
|
||||
this.parent = null;
|
||||
this.status = null;
|
||||
this.content = {};
|
||||
|
||||
if (split.parent) {
|
||||
this.parent = cache[split.parent] || new Entry(split.parent);
|
||||
this.parent.content[this.absHref] = this;
|
||||
}
|
||||
},
|
||||
|
||||
get = function (absHref, time, size, status) {
|
||||
|
||||
absHref = absHref || location;
|
||||
|
||||
var self = cache[absHref] || new Entry(absHref);
|
||||
|
||||
if (_.isNumber(time)) {
|
||||
self.time = time;
|
||||
}
|
||||
if (_.isNumber(size)) {
|
||||
self.size = size;
|
||||
}
|
||||
if (status) {
|
||||
self.status = status;
|
||||
}
|
||||
|
||||
return self;
|
||||
},
|
||||
|
||||
folderstatus = module.isDefined('ext/folderstatus') ? module.require('ext/folderstatus') : {},
|
||||
|
||||
fetchStatus = function (absHref, callback) {
|
||||
|
||||
var self = cache[absHref] || new Entry(absHref);
|
||||
|
||||
if (self.status || !self.isFolder()) {
|
||||
callback(self);
|
||||
} else if (folderstatus[absHref]) {
|
||||
self.status = folderstatus[absHref];
|
||||
callback(self);
|
||||
} else {
|
||||
ajaxRequest(self, null, callback);
|
||||
}
|
||||
},
|
||||
|
||||
fetchContent = function (absHref, parser, callback) {
|
||||
|
||||
var self = cache[absHref] || new Entry(absHref);
|
||||
|
||||
if (self.isContentFetched || _.keys(self.content).length > 1) {
|
||||
self.isContentFetched = true;
|
||||
callback(self);
|
||||
} else {
|
||||
fetchStatus(absHref, function (self) {
|
||||
|
||||
self.isContentFetched = true;
|
||||
if (self.status === 'h5ai') {
|
||||
ajaxRequest(self, parser, callback);
|
||||
} else {
|
||||
callback(self);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
_.extend(Entry.prototype, {
|
||||
|
||||
isFolder: function () {
|
||||
|
||||
return pathEndsWithSlash(this.absHref);
|
||||
},
|
||||
|
||||
isCurrentFolder: function () {
|
||||
|
||||
return this.absHref === location;
|
||||
},
|
||||
|
||||
isDomain: function () {
|
||||
|
||||
return this.absHref === '/';
|
||||
},
|
||||
|
||||
isEmpty: function () {
|
||||
|
||||
return _.keys(this.content).length === 0;
|
||||
},
|
||||
|
||||
fetchStatus: function (callback) {
|
||||
|
||||
return fetchStatus(this.absHref, callback);
|
||||
},
|
||||
|
||||
fetchContent: function (parser, callback) {
|
||||
|
||||
return fetchContent(this.absHref, parser, callback);
|
||||
},
|
||||
|
||||
getCrumb: function () {
|
||||
|
||||
var entry = this,
|
||||
crumb = [entry];
|
||||
|
||||
while (entry.parent) {
|
||||
entry = entry.parent;
|
||||
crumb.unshift(entry);
|
||||
}
|
||||
|
||||
return crumb;
|
||||
},
|
||||
|
||||
getSubfolders: function () {
|
||||
|
||||
return _.sortBy(_.filter(this.content, function (entry) {
|
||||
|
||||
return entry.isFolder();
|
||||
}), function (entry) {
|
||||
|
||||
return entry.absHref;
|
||||
});
|
||||
},
|
||||
|
||||
getStats: function () {
|
||||
|
||||
var folders = 0,
|
||||
files = 0;
|
||||
|
||||
_.each(this.content, function (entry) {
|
||||
|
||||
if (entry.isFolder()) {
|
||||
folders += 1;
|
||||
} else {
|
||||
files += 1;
|
||||
}
|
||||
});
|
||||
|
||||
var depth = 0,
|
||||
entry = this;
|
||||
|
||||
while (entry.parent) {
|
||||
depth += 1;
|
||||
entry = entry.parent;
|
||||
}
|
||||
|
||||
return {
|
||||
folders: folders,
|
||||
files: files,
|
||||
depth: depth
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
get: get
|
||||
};
|
||||
});
|
|
@ -1,174 +0,0 @@
|
|||
|
||||
var Module = window.Module = (function ($) {
|
||||
|
||||
var definitions = {},
|
||||
modules = {},
|
||||
|
||||
err = function (message) {
|
||||
|
||||
$.error('module: ' + message);
|
||||
},
|
||||
|
||||
uniq = function (array) {
|
||||
|
||||
var set = {},
|
||||
uniq = [];
|
||||
|
||||
$.each(array, function (idx, element) {
|
||||
|
||||
if (!set[element]) {
|
||||
set[element] = true;
|
||||
uniq.push(element);
|
||||
}
|
||||
});
|
||||
return uniq;
|
||||
},
|
||||
|
||||
depsIntern = function (ids) {
|
||||
|
||||
var self = this;
|
||||
var deps = [];
|
||||
|
||||
if (typeof ids === 'string') {
|
||||
|
||||
var def = definitions[ids];
|
||||
if (def) {
|
||||
$.each(def.deps, function (idx, id) {
|
||||
|
||||
deps = deps.concat(depsIntern(id));
|
||||
});
|
||||
deps.push(def.id);
|
||||
} else {
|
||||
deps.push(ids);
|
||||
}
|
||||
} else if ($.isArray(ids)) {
|
||||
|
||||
$.each(ids, function (idx, id) {
|
||||
|
||||
deps = deps.concat(depsIntern(id));
|
||||
});
|
||||
}
|
||||
|
||||
return uniq(deps);
|
||||
},
|
||||
|
||||
deps = function (ids) {
|
||||
|
||||
if (ids) {
|
||||
try {
|
||||
return depsIntern(ids);
|
||||
} catch (e) {
|
||||
err('cyclic dependencies for ids "' + ids + '"');
|
||||
}
|
||||
} else {
|
||||
var res = {};
|
||||
$.each(definitions, function (id, def) {
|
||||
|
||||
res[id] = deps(id);
|
||||
});
|
||||
return res;
|
||||
}
|
||||
},
|
||||
|
||||
log = function () {
|
||||
|
||||
var allDeps = deps(),
|
||||
allInvDeps = {};
|
||||
|
||||
$.each(definitions, function (id, def) {
|
||||
|
||||
var invDeps = [];
|
||||
$.each(allDeps, function (i, depId) {
|
||||
|
||||
if ($.inArray(id, depId) >= 0) {
|
||||
invDeps.push(i);
|
||||
}
|
||||
});
|
||||
allInvDeps[id] = invDeps;
|
||||
});
|
||||
|
||||
$.each(allDeps, function (id, deps) {
|
||||
|
||||
deps.pop();
|
||||
console.log(id + ' -> [ ' + deps.join(', ') + ' ]');
|
||||
});
|
||||
|
||||
console.log('\n');
|
||||
$.each(allInvDeps, function (id, invDeps) {
|
||||
|
||||
invDeps.shift();
|
||||
console.log(id + ' <- [ ' + invDeps.join(', ') + ' ]');
|
||||
});
|
||||
},
|
||||
|
||||
defs = function () {
|
||||
|
||||
return $.extend({}, definitions);
|
||||
},
|
||||
|
||||
mods = function () {
|
||||
|
||||
return $.extend({}, modules);
|
||||
},
|
||||
|
||||
define = function (id, deps, fn) {
|
||||
|
||||
if ($.isFunction(deps)) {
|
||||
fn = deps;
|
||||
deps = [];
|
||||
}
|
||||
if (typeof id !== 'string') {
|
||||
err('id must be a string "' + id + '"');
|
||||
}
|
||||
if (!$.isArray(deps)) {
|
||||
err('dependencies must be an array "' + deps + '"');
|
||||
}
|
||||
if (!$.isFunction(fn)) {
|
||||
err('constructor must be a function "' + fn + '"');
|
||||
}
|
||||
if (definitions[id]) {
|
||||
err('id already defined "' + id + '"');
|
||||
}
|
||||
|
||||
definitions[id] = {
|
||||
id: id,
|
||||
deps: deps,
|
||||
fn: fn
|
||||
};
|
||||
},
|
||||
|
||||
require = function (id) {
|
||||
|
||||
if (typeof id !== 'string') {
|
||||
return id;
|
||||
}
|
||||
|
||||
if (modules[id]) {
|
||||
return modules[id];
|
||||
}
|
||||
|
||||
var def = definitions[id];
|
||||
if (!def) {
|
||||
err('id not defined "' + id + '"');
|
||||
}
|
||||
|
||||
var deps = $.map(def.deps, function (depId) {
|
||||
|
||||
return require(depId);
|
||||
});
|
||||
|
||||
var obj = def.fn.apply(this, deps);
|
||||
modules[id] = obj;
|
||||
return obj;
|
||||
};
|
||||
|
||||
return {
|
||||
deps: deps,
|
||||
log: log,
|
||||
defs: defs,
|
||||
mods: mods,
|
||||
define: define,
|
||||
require: require
|
||||
};
|
||||
|
||||
}(jQuery));
|
42
src/_h5ai/js/inc/parser/apache-autoindex.js
Normal file
42
src/_h5ai/js/inc/parser/apache-autoindex.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
module.define('parser/apache-autoindex', [jQuery, 'core/format', 'model/entry'], function ($, format, Entry) {
|
||||
|
||||
var parseTableRow = function (absHref, tr) {
|
||||
|
||||
var $tds = $(tr).find('td'),
|
||||
$a = $tds.eq(1).find('a'),
|
||||
label = $a.text(),
|
||||
time = format.parseDate($tds.eq(2).text(), 'DD-MMM-YYYY HH:mm'),
|
||||
size = format.parseSize($tds.eq(3).text());
|
||||
|
||||
absHref = absHref + $a.attr('href');
|
||||
|
||||
return label === 'Parent Directory' ? null : Entry.get(absHref, time, size);
|
||||
},
|
||||
|
||||
parseTable = function (absHref, table) {
|
||||
|
||||
return _.compact(_.map($(table).find('td').closest('tr'), function (tr) {
|
||||
|
||||
return parseTableRow(absHref, tr);
|
||||
}));
|
||||
},
|
||||
|
||||
parse = function (absHref, html) {
|
||||
|
||||
var id = '#data-apache-autoindex',
|
||||
$html = $(html),
|
||||
$id = $html.filter(id);
|
||||
|
||||
if (!$id.length) {
|
||||
$id = $html.find(id);
|
||||
}
|
||||
|
||||
return parseTable(absHref, $id.find('table'));
|
||||
};
|
||||
|
||||
return {
|
||||
id: 'apache-autoindex',
|
||||
parse: parse
|
||||
};
|
||||
});
|
48
src/_h5ai/js/inc/parser/generic-json.js
Normal file
48
src/_h5ai/js/inc/parser/generic-json.js
Normal file
|
@ -0,0 +1,48 @@
|
|||
|
||||
module.define('parser/generic-json', [jQuery, 'core/settings', 'model/entry'], function ($, settings, Entry) {
|
||||
|
||||
// expectes an hash of the form
|
||||
// {
|
||||
// entries: [
|
||||
// {absHref: String, time: Number, size: Number, status: Number or "h5ai"}
|
||||
// ]
|
||||
// }
|
||||
|
||||
var parseJson = function (absHref, json) {
|
||||
|
||||
_.each(json.entries, function (jsonEntry) {
|
||||
|
||||
Entry.get(jsonEntry.absHref, jsonEntry.time, jsonEntry.size, jsonEntry.status);
|
||||
});
|
||||
|
||||
if (json.hasOwnProperty('customHeader')) {
|
||||
settings.custom.header = json.customHeader;
|
||||
}
|
||||
if (json.hasOwnProperty('customFooter')) {
|
||||
settings.custom.footer = json.customFooter;
|
||||
}
|
||||
},
|
||||
|
||||
parseJsonStr = function (absHref, jsonStr) {
|
||||
|
||||
return parseJson(absHref, JSON.parse($.trim(jsonStr) || '{}'));
|
||||
},
|
||||
|
||||
parse = function (absHref, html) {
|
||||
|
||||
var id = '#data-generic-json',
|
||||
$html = $(html),
|
||||
$id = $html.filter(id);
|
||||
|
||||
if (!$id.length) {
|
||||
$id = $html.find(id);
|
||||
}
|
||||
|
||||
return parseJsonStr(absHref, $id.text());
|
||||
};
|
||||
|
||||
return {
|
||||
id: 'generic-json',
|
||||
parse: parse
|
||||
};
|
||||
});
|
|
@ -1,98 +0,0 @@
|
|||
|
||||
Module.define('path', [jQuery, 'settings', 'util', 'core'], function ($, settings, util, core) {
|
||||
|
||||
var create = function (folder, tableRow) {
|
||||
|
||||
var path = {},
|
||||
$tds, $a, time, size, splits;
|
||||
|
||||
// path.parentFolder: undefined
|
||||
// path.label: undefined
|
||||
// path.type: undefined
|
||||
// path.href: undefined
|
||||
// path.time: undefined
|
||||
// path.size: undefined
|
||||
// path.absHref: undefined
|
||||
// path.isFolder: undefined
|
||||
// path.isParentFolder: undefined
|
||||
// path.isCurrentFolder: undefined
|
||||
// path.isDomain: undefined
|
||||
|
||||
path.status = undefined; // undefined, 'h5ai' or HTTP response code
|
||||
path.content = undefined; // associative array path.absHref -> path
|
||||
path.html = {
|
||||
$crumb: undefined,
|
||||
$extended: undefined,
|
||||
$tree: undefined
|
||||
};
|
||||
path.treeOpen = false;
|
||||
|
||||
if (!util.pathEndsWithSlash(folder)) {
|
||||
folder += '/';
|
||||
}
|
||||
|
||||
if (tableRow) {
|
||||
$tds = $(tableRow).find('td');
|
||||
$a = $tds.eq(1).find('a');
|
||||
time = Date.parse($tds.eq(2).text()) || 0;
|
||||
size = util.parseSize($tds.eq(3).text());
|
||||
|
||||
path.parentFolder = folder;
|
||||
path.label = $a.text();
|
||||
path.type = util.pathEndsWithSlash(path.label) ? 'folder' : core.getFileType(path.label);
|
||||
path.href = $a.attr('href');
|
||||
path.time = time;
|
||||
path.size = size;
|
||||
} else {
|
||||
splits = util.splitPath(folder);
|
||||
|
||||
path.parentFolder = splits.parent || '';
|
||||
path.label = util.checkedDecodeUri(splits.name);
|
||||
if (path.label === '/') {
|
||||
path.label = util.checkedDecodeUri(document.domain);
|
||||
}
|
||||
path.type = 'folder';
|
||||
path.href = splits.name;
|
||||
path.time = 0;
|
||||
path.size = -1;
|
||||
}
|
||||
|
||||
if (util.pathEndsWithSlash(path.label)) {
|
||||
path.label = path.label.slice(0, -1);
|
||||
}
|
||||
|
||||
path.isFolder = (path.type === 'folder');
|
||||
path.isParentFolder = (path.label === 'Parent Directory');
|
||||
if (path.isParentFolder) {
|
||||
path.isFolder = true;
|
||||
path.type = 'folder-parent';
|
||||
}
|
||||
path.absHref = path.isParentFolder ? path.href : path.parentFolder + path.href;
|
||||
path.isCurrentFolder = (path.absHref === document.location.pathname);
|
||||
path.isDomain = (path.absHref === '/');
|
||||
|
||||
if (path.isParentFolder && settings.setParentFolderLabels) {
|
||||
if (path.isDomain) {
|
||||
path.label = util.checkedDecodeUri(document.domain);
|
||||
} else {
|
||||
splits = util.splitPath(path.parentFolder);
|
||||
path.label = util.checkedDecodeUri(splits.parentname);
|
||||
}
|
||||
}
|
||||
|
||||
path.isEmpty = function () {
|
||||
|
||||
return !path.content || $.isEmptyObject(path.content);
|
||||
};
|
||||
path.onClick = function (context) {
|
||||
|
||||
core.triggerPathClick(path, context);
|
||||
};
|
||||
|
||||
return path;
|
||||
};
|
||||
|
||||
return {
|
||||
create: create
|
||||
};
|
||||
});
|
|
@ -1,57 +0,0 @@
|
|||
|
||||
Module.define('config', [jQuery, H5AI_CONFIG], function ($, config) {
|
||||
|
||||
var defaults = {
|
||||
store: {
|
||||
viewmode: 'h5ai.pref.viewmode',
|
||||
lang: 'h5ai.pref.lang'
|
||||
},
|
||||
callbacks: {
|
||||
pathClick: []
|
||||
},
|
||||
|
||||
rootAbsHref: '/',
|
||||
h5aiAbsHref: '/_h5ai/',
|
||||
customHeader: null,
|
||||
customFooter: null,
|
||||
viewmodes: ['details', 'icons'],
|
||||
sortorder: 'na',
|
||||
showTree: true,
|
||||
slideTree: true,
|
||||
folderStatus: {},
|
||||
lang: 'en',
|
||||
useBrowserLang: true,
|
||||
setParentFolderLabels: true,
|
||||
linkHoverStates: true,
|
||||
dateFormat: 'yyyy-MM-dd HH:mm',
|
||||
showThumbs: false,
|
||||
thumbTypes: ['bmp', 'gif', 'ico', 'image', 'jpg', 'png', 'tiff'],
|
||||
zippedDownload: false,
|
||||
qrCodesSize: null,
|
||||
showFilter: false
|
||||
};
|
||||
|
||||
return {
|
||||
settings: $.extend({}, defaults, config.options),
|
||||
types: $.extend({}, config.types),
|
||||
langs: $.extend({}, config.langs)
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Module.define('settings', ['config'], function (config) {
|
||||
|
||||
return config.settings;
|
||||
});
|
||||
|
||||
|
||||
Module.define('types', ['config'], function (config) {
|
||||
|
||||
return config.types;
|
||||
});
|
||||
|
||||
|
||||
Module.define('langs', ['config'], function (config) {
|
||||
|
||||
return config.langs;
|
||||
});
|
|
@ -1,117 +0,0 @@
|
|||
|
||||
Module.define('util', [jQuery], function ($) {
|
||||
|
||||
var reSplitPath = /^\/([^\/]+\/?)$/,
|
||||
reSplitPath2 = /^(\/(?:.*\/)*?([^\/]+)\/)([^\/]+\/?)$/,
|
||||
rePathEndsWithSlash = /\/$/,
|
||||
reParseSize = /^\s*([\.\d]+)\s*([kmg]?)b?\s*$/i,
|
||||
kilo = 1000.0,
|
||||
sizeUnits = ['B', 'KB', 'MB', 'GB', 'TB'],
|
||||
|
||||
splitPath = function (pathname) {
|
||||
|
||||
var match;
|
||||
|
||||
if (pathname === '/') {
|
||||
return {
|
||||
parent: null,
|
||||
parentname: null,
|
||||
name: '/'
|
||||
};
|
||||
}
|
||||
match = reSplitPath2.exec(pathname);
|
||||
if (match) {
|
||||
return {
|
||||
parent: match[1],
|
||||
parentname: match[2],
|
||||
name: match[3]
|
||||
};
|
||||
}
|
||||
match = reSplitPath.exec(pathname);
|
||||
if (match) {
|
||||
return {
|
||||
parent: '/',
|
||||
parentname: '/',
|
||||
name: match[1]
|
||||
};
|
||||
}
|
||||
},
|
||||
pathEndsWithSlash = function (pathname) {
|
||||
|
||||
return rePathEndsWithSlash.test(pathname);
|
||||
},
|
||||
getAbsHref = function (folder, tableRow) {
|
||||
|
||||
var $a, isParentFolder, href;
|
||||
|
||||
if (!pathEndsWithSlash(folder)) {
|
||||
folder += '/';
|
||||
}
|
||||
if (!tableRow) {
|
||||
return folder;
|
||||
}
|
||||
$a = $(tableRow).find('td').eq(1).find('a');
|
||||
isParentFolder = ($a.text() === 'Parent Directory');
|
||||
href = $a.attr('href');
|
||||
return isParentFolder ? undefined : folder + href;
|
||||
},
|
||||
parseSize = function (str) {
|
||||
|
||||
var match = reParseSize.exec(str),
|
||||
val, unit;
|
||||
|
||||
if (!match) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = parseFloat(match[1]);
|
||||
unit = match[2].toLowerCase();
|
||||
if (unit === 'k') {
|
||||
val *= kilo;
|
||||
} else if (unit === 'm') {
|
||||
val *= kilo * kilo;
|
||||
} else if (unit === 'g') {
|
||||
val *= kilo * kilo * kilo;
|
||||
} else if (unit === 't') {
|
||||
val *= kilo * kilo * kilo * kilo;
|
||||
}
|
||||
return val;
|
||||
},
|
||||
formatSize = function (size) {
|
||||
|
||||
var th = 1000.0,
|
||||
i = 0,
|
||||
maxI = sizeUnits.length - 1;
|
||||
|
||||
if (isNaN(size)) {
|
||||
return size;
|
||||
}
|
||||
|
||||
while (size >= th && i < maxI) {
|
||||
size /= kilo;
|
||||
i += 1;
|
||||
}
|
||||
return (i <= 1 ? Math.round(size) : size.toFixed(1)).toString() + ' ' + sizeUnits[i];
|
||||
},
|
||||
checkedDecodeUri = function (uri) {
|
||||
|
||||
try {
|
||||
return decodeURI(uri);
|
||||
} catch (err) {}
|
||||
return uri;
|
||||
},
|
||||
reEscape = function (sequence) {
|
||||
|
||||
return sequence.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
|
||||
};
|
||||
|
||||
return {
|
||||
splitPath: splitPath,
|
||||
pathEndsWithSlash: pathEndsWithSlash,
|
||||
getAbsHref: getAbsHref,
|
||||
parseSize: parseSize,
|
||||
formatSize: formatSize,
|
||||
checkedDecodeUri: checkedDecodeUri,
|
||||
reEscape: reEscape
|
||||
};
|
||||
});
|
135
src/_h5ai/js/inc/view/extended.js
Normal file
135
src/_h5ai/js/inc/view/extended.js
Normal file
|
@ -0,0 +1,135 @@
|
|||
|
||||
module.define('view/extended', [jQuery, 'core/settings', 'core/resource', 'core/format', 'core/event', 'core/entry'], function ($, allsettings, resource, format, event, entry) {
|
||||
|
||||
var defaults = {
|
||||
modes: ['details', 'icons'],
|
||||
setParentFolderLabels: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.view),
|
||||
|
||||
template = '<li class="entry">' +
|
||||
'<a>' +
|
||||
'<span class="icon small"><img /></span>' +
|
||||
'<span class="icon big"><img /></span>' +
|
||||
'<span class="label" />' +
|
||||
'<span class="date" />' +
|
||||
'<span class="size" />' +
|
||||
'</a>' +
|
||||
'</li>',
|
||||
hintTemplate = '<span class="hint"></span>',
|
||||
listTemplate = '<ul>' +
|
||||
'<li class="header">' +
|
||||
'<a class="icon"></a>' +
|
||||
'<a class="label" href="#"><span class="l10n-name"></span></a>' +
|
||||
'<a class="date" href="#"><span class="l10n-lastModified"></span></a>' +
|
||||
'<a class="size" href="#"><span class="l10n-size"></span></a>' +
|
||||
'</li>' +
|
||||
'</ul>',
|
||||
emptyTemplate = '<div class="empty l10n-empty">empty</div>',
|
||||
|
||||
|
||||
|
||||
// updates this single entry
|
||||
update = function (entry) {
|
||||
|
||||
if (entry.$extended && entry.status && entry.$extended.data('status') === entry.status) {
|
||||
return entry.$extended;
|
||||
}
|
||||
|
||||
var $html = $(template),
|
||||
$a = $html.find('a'),
|
||||
$imgSmall = $html.find('.icon.small img'),
|
||||
$imgBig = $html.find('.icon.big img'),
|
||||
$label = $html.find('.label'),
|
||||
$date = $html.find('.date'),
|
||||
$size = $html.find('.size'),
|
||||
icon16 = resource.icon(entry.type),
|
||||
icon48 = resource.icon(entry.type, true),
|
||||
escapedHref = entry.absHref.replace(/'/g, "%27").replace(/"/g, "%22");
|
||||
|
||||
$html
|
||||
.addClass(entry.isFolder() ? 'folder' : 'file')
|
||||
.data('entry', entry)
|
||||
.data('status', entry.status);
|
||||
|
||||
if (entry.isParentFolder) {
|
||||
icon16 = resource.icon('folder-parent');
|
||||
icon48 = resource.icon('folder-parent', true);
|
||||
if (!settings.setParentFolderLabels) {
|
||||
$label.addClass('l10n-parentDirectory');
|
||||
}
|
||||
$html.addClass('folder-parent');
|
||||
}
|
||||
|
||||
$a.attr('href', entry.absHref);
|
||||
$imgSmall.attr('src', icon16).attr('alt', entry.type);
|
||||
$imgBig.attr('src', icon48).attr('alt', entry.type);
|
||||
$label.text(entry.label);
|
||||
$date.data('time', entry.time).text(format.formatDate(entry.time));
|
||||
$size.data('bytes', entry.size).text(format.formatSize(entry.size));
|
||||
|
||||
if (entry.isFolder() && _.isNumber(entry.status)) {
|
||||
if (entry.status === 200) {
|
||||
$html.addClass('page');
|
||||
$imgSmall.attr('src', resource.icon('folder-page'));
|
||||
$imgBig.attr('src', resource.icon('folder-page', true));
|
||||
} else {
|
||||
$html.addClass('error');
|
||||
$label.append($(hintTemplate).text(' ' + entry.status + ' '));
|
||||
}
|
||||
}
|
||||
|
||||
if (entry.$extended) {
|
||||
entry.$extended.replaceWith($html);
|
||||
}
|
||||
entry.$extended = $html;
|
||||
|
||||
return $html;
|
||||
},
|
||||
|
||||
onMouseenter = function () {
|
||||
|
||||
var entry = $(this).closest('.entry').data('entry');
|
||||
event.pub('entry.mouseenter', entry);
|
||||
},
|
||||
|
||||
onMouseleave = function () {
|
||||
|
||||
var entry = $(this).closest('.entry').data('entry');
|
||||
event.pub('entry.mouseleave', entry);
|
||||
},
|
||||
|
||||
// creates the view for entry content
|
||||
init = function (entry) {
|
||||
|
||||
var $extended = $('#extended'),
|
||||
$ul = $(listTemplate);
|
||||
|
||||
if (entry.parent) {
|
||||
$ul.append(update(entry.parent));
|
||||
}
|
||||
|
||||
_.each(entry.content, function (e) {
|
||||
|
||||
$ul.append(update(e));
|
||||
|
||||
e.fetchStatus(function (e) {
|
||||
|
||||
update(e);
|
||||
});
|
||||
});
|
||||
|
||||
$extended.append($ul);
|
||||
|
||||
if (entry.isEmpty()) {
|
||||
$extended.append($(emptyTemplate));
|
||||
}
|
||||
|
||||
$extended
|
||||
.on('mouseenter', '.entry a', onMouseenter)
|
||||
.on('mouseleave', '.entry a', onMouseleave);
|
||||
};
|
||||
|
||||
init(entry);
|
||||
});
|
35
src/_h5ai/js/inc/view/spacing.js
Normal file
35
src/_h5ai/js/inc/view/spacing.js
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
module.define('view/spacing', [jQuery, 'core/settings', 'core/event'], function ($, allsettings, event) {
|
||||
|
||||
var defaults = {
|
||||
maxWidth: 960,
|
||||
top: 50,
|
||||
right: "auto",
|
||||
bottom: 50,
|
||||
left: "auto"
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.spacing),
|
||||
|
||||
adjustSpacing = function () {
|
||||
|
||||
$('#content').css({
|
||||
'margin-top': settings.top + $('#topbar').outerHeight(),
|
||||
'margin-bottom': settings.bottom + $('#bottombar').outerHeight()
|
||||
});
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
$('#content').css({
|
||||
'max-width': settings.maxWidth,
|
||||
'margin-right': settings.right,
|
||||
'margin-left': settings.left
|
||||
});
|
||||
|
||||
event.sub('ready', adjustSpacing);
|
||||
$(window).on('resize', adjustSpacing);
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
77
src/_h5ai/js/inc/view/viewmode.js
Normal file
77
src/_h5ai/js/inc/view/viewmode.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
|
||||
module.define('view/viewmode', [jQuery, 'core/settings', 'core/resource', 'core/store'], function ($, allsettings, resource, store) {
|
||||
|
||||
var defaults = {
|
||||
modes: ['details', 'icons'],
|
||||
setParentFolderLabels: false
|
||||
},
|
||||
|
||||
settings = _.extend({}, defaults, allsettings.view),
|
||||
|
||||
storekey = 'h5ai.viewmode',
|
||||
|
||||
templates = {
|
||||
details: '<li id="viewdetails" class="view">' +
|
||||
'<a href="#">' +
|
||||
'<img src="' + resource.image('view-details') + '" alt="view-details" />' +
|
||||
'<span class="l10n-details">details</span>' +
|
||||
'</a>' +
|
||||
'</li>',
|
||||
icons: '<li id="viewicons" class="view">' +
|
||||
'<a href="#">' +
|
||||
'<img src="' + resource.image('view-icons') + '" alt="view-icons" />' +
|
||||
'<span class="l10n-icons">icons</span>' +
|
||||
'</a>' +
|
||||
'</li>'
|
||||
},
|
||||
|
||||
update = function (viewmode) {
|
||||
|
||||
var $viewDetails = $('#viewdetails'),
|
||||
$viewIcons = $('#viewicons'),
|
||||
$extended = $('#extended');
|
||||
|
||||
if (viewmode) {
|
||||
store.put(storekey, viewmode);
|
||||
} else {
|
||||
viewmode = store.get(storekey);
|
||||
}
|
||||
viewmode = $.inArray(viewmode, settings.modes) >= 0 ? viewmode : settings.modes[0];
|
||||
|
||||
$viewDetails.add($viewIcons).removeClass('current');
|
||||
if (viewmode === 'details') {
|
||||
$viewDetails.addClass('current');
|
||||
$extended.addClass('details-view').removeClass('icons-view').show();
|
||||
} else if (viewmode === 'icons') {
|
||||
$viewIcons.addClass('current');
|
||||
$extended.removeClass('details-view').addClass('icons-view').show();
|
||||
} else {
|
||||
$extended.hide();
|
||||
}
|
||||
},
|
||||
|
||||
init = function () {
|
||||
|
||||
var $navbar = $('#navbar'),
|
||||
$extended = $('#extended');
|
||||
|
||||
settings.modes = _.intersection(settings.modes, defaults.modes);
|
||||
|
||||
if (settings.modes.length > 1) {
|
||||
_.each(['icons', 'details'], function (view) {
|
||||
if ($.inArray(view, settings.modes) >= 0) {
|
||||
$(templates[view])
|
||||
.appendTo($navbar)
|
||||
.on('click', 'a', function (event) {
|
||||
update(view);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
update();
|
||||
};
|
||||
|
||||
init();
|
||||
});
|
|
@ -1,187 +0,0 @@
|
|||
|
||||
Module.define('zip', [jQuery, 'settings', 'core'], function ($, settings, core) {
|
||||
|
||||
var x = 0,
|
||||
y = 0,
|
||||
$document = $(document),
|
||||
$selectionRect = $('#selection-rect'),
|
||||
selectedHrefsStr = '',
|
||||
$download, $img, $downloadAuth, $downloadUser, $downloadPassword,
|
||||
|
||||
updateDownloadBtn = function () {
|
||||
|
||||
var $selected = $('#extended a.selected'),
|
||||
$downloadBtn = $('#download');
|
||||
|
||||
selectedHrefsStr = '';
|
||||
if ($selected.length) {
|
||||
$selected.each(function () {
|
||||
|
||||
var href = $(this).attr('href');
|
||||
selectedHrefsStr = selectedHrefsStr ? selectedHrefsStr + ':' + href : href;
|
||||
});
|
||||
$downloadBtn.show();
|
||||
} else {
|
||||
$downloadBtn.hide();
|
||||
$downloadAuth.hide();
|
||||
}
|
||||
},
|
||||
selectionUpdate = function (event) {
|
||||
|
||||
var l = Math.min(x, event.pageX),
|
||||
t = Math.min(y, event.pageY),
|
||||
w = Math.abs(x - event.pageX),
|
||||
h = Math.abs(y - event.pageY),
|
||||
selRect;
|
||||
|
||||
event.preventDefault();
|
||||
$selectionRect.css({left: l, top: t, width: w, height: h});
|
||||
|
||||
selRect = $selectionRect.fracs('rect');
|
||||
$('#extended a').removeClass('selecting').each(function () {
|
||||
|
||||
var $a = $(this),
|
||||
rect = $a.fracs('rect'),
|
||||
inter = selRect.intersection(rect);
|
||||
if (inter && !$a.closest('.entry').hasClass('folder-parent')) {
|
||||
$a.addClass('selecting');
|
||||
}
|
||||
});
|
||||
},
|
||||
selectionEnd = function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$document.off('mousemove', selectionUpdate);
|
||||
$selectionRect.hide().css({left: 0, top: 0, width: 0, height: 0});
|
||||
$('#extended a.selecting.selected').removeClass('selecting').removeClass('selected');
|
||||
$('#extended a.selecting').removeClass('selecting').addClass('selected');
|
||||
updateDownloadBtn();
|
||||
},
|
||||
selectionStart = function (event) {
|
||||
|
||||
var view = $(document).fracs('viewport');
|
||||
|
||||
x = event.pageX;
|
||||
y = event.pageY;
|
||||
// only on left button and don't block the scrollbars
|
||||
if (event.button !== 0 || x >= view.right || y >= view.bottom) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
$(':focus').blur();
|
||||
if (!event.ctrlKey) {
|
||||
$("#extended a").removeClass("selected");
|
||||
updateDownloadBtn();
|
||||
}
|
||||
$selectionRect.show().css({left: x, top: y, width: 0, height: 0});
|
||||
|
||||
$document
|
||||
.on("mousemove", selectionUpdate)
|
||||
.one("mouseup", selectionEnd);
|
||||
},
|
||||
noSelection = function (event) {
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
return false;
|
||||
},
|
||||
noSelectionUnlessCtrl = function (event) {
|
||||
|
||||
if (!event.ctrlKey) {
|
||||
noSelection(event);
|
||||
}
|
||||
},
|
||||
failed = function () {
|
||||
|
||||
$download.addClass('failed');
|
||||
setTimeout(function () {
|
||||
$download.removeClass('failed');
|
||||
}, 1000);
|
||||
},
|
||||
handleResponse = function (response) {
|
||||
|
||||
|
||||
$download.removeClass('current');
|
||||
$img.attr('src', core.image("download"));
|
||||
|
||||
if (response) {
|
||||
if (response.status === 'ok') {
|
||||
window.location = core.api() + '?action=getzip&id=' + response.id;
|
||||
} else {
|
||||
if (response.code === 401) {
|
||||
$downloadAuth
|
||||
.css({
|
||||
left: $download.offset().left,
|
||||
top: $download.offset().top + $download.outerHeight()
|
||||
})
|
||||
.show();
|
||||
$downloadUser.focus();
|
||||
}
|
||||
failed();
|
||||
}
|
||||
} else {
|
||||
failed();
|
||||
}
|
||||
},
|
||||
requestZipping = function (hrefsStr) {
|
||||
|
||||
$download.addClass('current');
|
||||
$img.attr('src', core.image("loading.gif", true));
|
||||
$.ajax({
|
||||
url: core.api(),
|
||||
data: {
|
||||
action: 'zip',
|
||||
hrefs: selectedHrefsStr
|
||||
},
|
||||
type: 'POST',
|
||||
dataType: 'json',
|
||||
beforeSend: function (xhr) {
|
||||
|
||||
var user = $downloadUser.val(),
|
||||
password = $downloadPassword.val();
|
||||
|
||||
if (user) {
|
||||
xhr.setRequestHeader ('Authorization', 'Basic ' + Base64.encode(user + ':' + password));
|
||||
}
|
||||
},
|
||||
success: function (response) {
|
||||
|
||||
handleResponse(response);
|
||||
},
|
||||
error: function () {
|
||||
|
||||
handleResponse();
|
||||
}
|
||||
});
|
||||
},
|
||||
init = function () {
|
||||
|
||||
if (settings.zippedDownload) {
|
||||
$('<li id="download"><a href="#"><img alt="download" /><span class="l10n-download">download</span></a></li>')
|
||||
.find('img').attr('src', core.image('download')).end()
|
||||
.find('a').click(function (event) {
|
||||
|
||||
event.preventDefault();
|
||||
$downloadAuth.hide();
|
||||
requestZipping(selectedHrefsStr);
|
||||
}).end()
|
||||
.appendTo($('#navbar'));
|
||||
$('<div id="download-auth"><input id="download-auth-user" type="text" value="" placeholder="user" /><input id="download-auth-password" type="text" value="" placeholder="password" /></div>')
|
||||
.appendTo($('body'));
|
||||
|
||||
$download = $('#download');
|
||||
$downloadAuth = $('#download-auth');
|
||||
$downloadUser = $('#download-auth-user');
|
||||
$downloadPassword = $('#download-auth-password');
|
||||
$img = $download.find('img');
|
||||
|
||||
$('body>nav,body>footer,#tree,input').on('mousedown', noSelection);
|
||||
$('#content').on('mousedown', 'a', noSelectionUnlessCtrl);
|
||||
$document.on('mousedown', selectionStart);
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
});
|
4
src/_h5ai/js/modernizr-2.5.3.min.js
vendored
Normal file
4
src/_h5ai/js/modernizr-2.5.3.min.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
/* Modernizr 2.5.3 (Custom Build) | MIT & BSD
|
||||
* Build: http://www.modernizr.com/download/#-opacity-rgba-canvas-history-audio-video-shiv-cssclasses-prefixes
|
||||
*/
|
||||
;window.Modernizr=function(a,b,c){function v(a){j.cssText=a}function w(a,b){return v(m.join(a+";")+(b||""))}function x(a,b){return typeof a===b}function y(a,b){return!!~(""+a).indexOf(b)}function z(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:x(f,"function")?f.bind(d||b):f}return!1}var d="2.5.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n={},o={},p={},q=[],r=q.slice,s,t={}.hasOwnProperty,u;!x(t,"undefined")&&!x(t.call,"undefined")?u=function(a,b){return t.call(a,b)}:u=function(a,b){return b in a&&x(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=r.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(r.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(r.call(arguments)))};return e}),n.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},n.history=function(){return!!a.history&&!!history.pushState},n.rgba=function(){return v("background-color:rgba(150,255,150,.5)"),y(j.backgroundColor,"rgba")},n.opacity=function(){return w("opacity:.55"),/^0.55$/.test(j.opacity)},n.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},n.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c};for(var A in n)u(n,A)&&(s=A.toLowerCase(),e[s]=n[A](),q.push((e[s]?"":"no-")+s));return v(""),i=k=null,function(a,b){function g(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="<xyz></xyz>",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,e._prefixes=m,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+q.join(" "):""),e}(this,this.document);
|
4
src/_h5ai/js/modernizr.min.js
vendored
4
src/_h5ai/js/modernizr.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,7 @@
|
|||
// ------------------
|
||||
// @include "inc/lib/jquery-1.7.1.min.js"
|
||||
// @include "inc/lib/jquery.fracs-0.11.min.js"
|
||||
// @include "inc/lib/jquery.mousewheel.js"
|
||||
// @include "inc/lib/jquery.mousewheel-3.0.6.js"
|
||||
// @include "inc/lib/jquery.qrcode.js"
|
||||
// @include "inc/lib/jquery.scrollpanel.js"
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
|||
// @include "inc/lib/json2.js"
|
||||
// @include "inc/lib/moment-1.5.0.min.js"
|
||||
// @include "inc/lib/underscore-1.3.1.min.js"
|
||||
// @include "inc/lib/module.js"
|
||||
|
||||
// h5ai
|
||||
// ----
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue