/*global $, Objects */ Objects.Path = function (pathCache, folder, tableRow) { var path, checkedDecodeUri = function (uri) { try { return decodeURI(uri); } catch (err) {} return uri; }, isEmpty = function () { return !path.content || $.isEmptyObject(path.content); }, onClick = function (context) { h5ai.triggerPathClick(path, context); }, updateHtml = function () { path.updateCrumbHtml(); path.updateExtendedHtml(); path.updateTreeHtml(); }, updateCrumbHtml = function () { var $html, $a; if (path.html.$crumb && path.html.$crumb.data("status") === path.status) { return path.html.$crumb; } $html = $("
  • ") .data("path", path) .addClass(path.isFolder ? "folder" : "file"); if (path.status) { $html.data("status", path.status); } $a = $(">" + path.label + "") .appendTo($html) .attr("href", path.absHref) .click(function() { onClick("crumb"); }); if (path.isDomain) { $html.addClass("domain"); $a.find("img").attr("src", "/h5ai/images/home.png"); } if (path.isCurrentFolder) { $html.addClass("current"); } if (!isNaN(path.status)) { if (path.status === 200) { $("not listable").appendTo($a); } else { $("(" + path.status + ")").appendTo($a); } } if (path.html.$crumb) { path.html.$cpathreplaceWith($html); } path.html.$crumb = $html; return $html; }, updateExtendedHtml = function () { var $html, $a, $label; if (path.html.$extended && path.html.$extended.data("status") === path.status) { return path.html.$extended; } $html = $("
  • ") .data("path", path) .addClass(path.isFolder ? "folder" : "file"); if (path.status) { $html.data("status", path.status); } $label = $("" + path.label + ""); $a = $("") .attr("href", path.absHref) .click(function() { onClick("extended"); }) .appendTo($html) .append($("" + path.alt + "")) .append($("" + path.alt + "")) .append($label) .append($("" + path.date + "")) .append($("" + path.size + "")); $a.hover( function () { if ($("#extended").hasClass("icons-view")) { var $this = $(this); $(".status.default").hide(); $(".status.dynamic") .empty() .append($this.find(".label").clone()) .append($("·")) .append($this.find(".date").clone()) .show(); if (!$this.closest(".entry").hasClass("folder")) { $(".status.dynamic") .append($("·")) .append($this.find(".size").clone()); } } }, function () { $(".status.default").show(); $(".status.dynamic").empty().hide(); } ); if (path.isParentFolder) { if (!h5ai.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", "/h5ai/icons/16x16/folder-page.png"); $a.find(".icon.big img").attr("src", "/h5ai/icons/48x48/folder-page.png"); } else { $html.addClass("error"); $label.append($(" " + path.status + " ")); } } if (path.html.$extended) { path.html.$extended.replaceWith($html); } path.html.$extended = $html; return $html; }, updateTreeHtml = function () { var $html, $blank, $a, $indicator, $ul, idx; $html = $("
    ") .data("path", path) .addClass(path.isFolder ? "folder" : "file"); $blank = $("").appendTo($html); $a = $("") .attr("href", path.absHref) .click(function() { path.onClick("tree"); }) .appendTo($html) .append($("")) .append($("" + path.label + "")); if (path.isFolder) { // indicator if (path.status === undefined || !path.isEmpty()) { $indicator = $(""); if (path.status === undefined) { $indicator.addClass("unknown"); } else if (path.treeOpen) { $indicator.addClass("open"); } $indicator.click(function(event) { if ($indicator.hasClass("unknown")) { tree.fetchStatusAndContent(path.absHref, false, function (status, content) { path.status = status; path.content = content; path.treeOpen = true; $("#tree").get(0).updateScrollbar(true); path.updateTreeHtml(function() { $("#tree").get(0).updateScrollbar(); }); }); } else if ($indicator.hasClass("open")) { path.treeOpen = false; $indicator.removeClass("open"); $("#tree").get(0).updateScrollbar(true); $html.find("> ul.content").slideUp(function() { $("#tree").get(0).updateScrollbar(); }); } else { path.treeOpen = true; $indicator.addClass("open"); $("#tree").get(0).updateScrollbar(true); $html.find("> ul.content").slideDown(function() { $("#tree").get(0).updateScrollbar(); }); } }); $html.addClass("initiatedIndicator"); $blank.replaceWith($indicator); } // is path the domain? if (path.isDomain) { $html.addClass("domain"); $a.find(".icon img").attr("src", "/h5ai/icons/16x16/folder-home.png"); } // is path the current folder? if (path.isCurrentFolder) { $html.addClass("current"); $a.find(".icon img").attr("src", "/h5ai/icons/16x16/folder-open.png"); } // does it have subfolders? if (!path.isEmpty()) { $ul = $("
      ").appendTo($html); $.each(path.content, function (idx, entry) { $("
    • ").append(entry.updateTreeHtml()).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", "/h5ai/icons/16x16/folder-page.png"); $a.append($("")); } else { $html.addClass("error"); $a.append($("" + path.status + "")); } } } if (path.html.$tree) { path.html.$tree.replaceWith($html); } path.html.$tree = $html; return $html; }, init = function () { var $tds, $img, $a, splits; path = { // parentFolder: undefined, // label: undefined, // date: undefined, // size: undefined, // href: undefined, // absHref: undefined, // alt: undefined, // icon16: undefined, // icon48: undefined, // isFolder: undefined, // isParentFolder: undefined, // isCurrentFolder: undefined, // isDomain: undefined, status: undefined, // undefined, "h5ai" or HTTP response code content: undefined, // associative array path.absHref -> path html: { $crumb: undefined, $extended: undefined, $tree: undefined }, treeOpen: false, isEmpty: isEmpty, onClick: onClick, updateHtml: updateHtml, updateCrumbHtml: updateCrumbHtml, updateExtendedHtml: updateExtendedHtml, updateTreeHtml: updateTreeHtml }; if (!pathCache.pathEndsWithSlash(folder)) { folder += "/"; } if (tableRow) { $tds = $(tableRow).find("td"); $img = $tds.eq(0).find("img"); $a = $tds.eq(1).find("a"); path.parentFolder = folder; path.label = $a.text(); path.date = $tds.eq(2).text(); path.size = $tds.eq(3).text(); path.href = $a.attr("href"); path.alt = $img.attr("alt"); path.icon16 = $img.attr("src"); } else { splits = pathCache.splitPathname(folder); path.parentFolder = splits[0]; path.label = checkedDecodeUri(splits[1]); if (path.label === "/") { path.label = checkedDecodeUri(document.domain) + "/"; } path.date = ""; path.size = ""; path.href = splits[1]; path.alt = "[DIR]"; path.icon16 = "/h5ai/icons/16x16/folder.png"; } if (pathCache.pathEndsWithSlash(path.label)) { path.label = path.label.slice(0, -1); } path.icon48 = path.icon16.replace("16x16", "48x48"); path.isFolder = (path.alt === "[DIR]"); path.isParentFolder = (path.isFolder && path.label === "Parent Directory"); path.absHref = path.isParentFolder ? path.href : path.parentFolder + path.href; path.isCurrentFolder = (path.absHref === document.location.pathname); path.isDomain = (path.absHref === "/"); if (path.isParentFolder && h5ai.settings.setParentFolderLabels) { if (path.isDomain) { path.label = checkedDecodeUri(document.domain); } else { path.label = checkedDecodeUri(pathCache.splitPathname(pathCache.splitPathname(path.parentFolder)[0])[1].slice(0, -1)); } } }; init(); return path; }; Objects.PathCache = function () { var pathCache, cache = {}, rePathnameSplit = /^(\/(.*\/)*)([^\/]+\/?)$/, rePathEndsWithSlash = /\/$/, splitPathname = function (pathname) { var match; if (pathname === "/") { return ["", "/"]; } match = rePathnameSplit.exec(pathname); return [match[1], match[3]]; }, 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; }, getPath = function (folder, tableRow) { var absHref = getAbsHref(folder, tableRow), path = cache[absHref]; if (!path) { path = new Objects.Path(pathCache, folder, tableRow); if (!path.isParentFolder) { cache[path.absHref] = path; } } return path; }; pathCache = { splitPathname: splitPathname, pathEndsWithSlash: pathEndsWithSlash, getPath: getPath, cache: cache }; return pathCache; };