var repoindex = (function(repoindex) { repoindex.softwareUpgradeBackgroundColor = "#dfffdd"; repoindex.packageUpgradeBackgroundColor = "#dde3ff"; repoindex.downgradesBackgroundColor = "#ffeecb"; repoindex.orphanedPackageBackgroundColor = "#fdd"; var PackageEntry = {}; PackageEntry.prototype = new repoindex.Entry(); PackageEntry.prototype.constructor = PackageEntry; PackageEntry = function(repoEntry, packageName, packageInfo, color) { this.repoEntry = repoEntry; // might be undefined repoindex.Entry.prototype.constructor.call(this, packageName, packageInfo); // init row element if(color) { this.rowElement.style.backgroundColor = color; } this.rowElement.onclick = function(e) { repoindex.pageManager.packageManager.showPackageInfoForIndex(this.entry.index, typeof e === "object" && e.button === 1); }; this.initTableRow = function() { var basics = this.info.basics ? this.info.basics : {}; var srcOnly = this.repoEntry && this.repoEntry.info.srcOnly; var pkgOnly = this.repoEntry && this.repoEntry.info.pkgOnly; var version = this.curVer ? (this.curVer + " → " + (basics.ver ? basics.ver : "?")) : basics.ver; var values = [srcOnly ? "n/a" : basics.arch, this.info.repo, this.name, version, basics.desc, srcOnly ? "n/a" : basics.bdate, pkgOnly ? "n/a" : basics.flagdate]; for(var i = 0; i < 7; ++i) { this.rowElement.addCell(repoindex.makeStr(values[i])); } }; this.initTableRow(); }; repoindex.PackageEntryManager = {}; repoindex.PackageEntryManager.prototype = new repoindex.EntryManager(); repoindex.PackageEntryManager = function(pagination, repoEntries) { repoindex.EntryManager.prototype.constructor.call(this, PackageEntry, document.getElementById("packages"), pagination, repoEntries); this.entryName = "package"; this.entryNamePlural = "packages"; this.containerName = "repository"; this.containerNamePlural = "repositories"; this.getContainerQuantity = repoindex.entryManagerGetRepoQuantity; this.createCustomEntry = function(repoEntry, packageName, packageInfo, color) { return new PackageEntry(repoEntry, packageName, packageInfo, color); }; this.addEntry = function(repoEntry, packageName, packageInfo) { packageInfo.repo = repoEntry.name; packageInfo.name = packageName; packageInfo.received = false; var entry = new PackageEntry(repoEntry, packageName, packageInfo); entry.index = this.entries.length; this.entries.push(entry); return entry; }; // handle a page selection this.pagination.pageSelected = function(pageElement) { var mgr = this.entryManager; // remove elements from previously selected page mgr.entryContainer.wipeChildren(); // if there is no page because there are no package entries, pageElement is null if(pageElement) { // show elements of selected page var packageSelection = {}; // package selection for requesting package info var entriesRequired = false; pageElement.forRange(function(i) { var entry = mgr.filteredEntries[i]; entry.add(mgr.entryContainer); if(!entry.info.basics) { var repoArray = packageSelection[entry.info.repo]; if(!Array.isArray(repoArray)) { packageSelection[entry.info.repo] = [{index: entry.info.index, name: entry.info.name}]; } else { repoArray.push({index: entry.info.index, name: entry.info.name}); } entriesRequired = true; } }, mgr.filteredEntries.length); var updateTableRows = function() { pageElement.forRange(function(i) { mgr.filteredEntries[i].updateTableRow(); }, mgr.filteredEntries.length); }; if(entriesRequired) { repoindex.client.requestBasicPackagesInfo(packageSelection, updateTableRows); } } }; this.infoBox = document.getElementById("packages_info"); this.showPackageInfo = function(repo, name, newTab) { var determineEntry = function() { var res = repoindex.pageManager.packageManager.entries.filter(function(entry) { return entry.info.repo === repo && entry.info.name === name; }); if(res.length > 0) { repoindex.pageManager.packageManager.showPackageInfoForIndex(res[0].index, newTab); } else { repoindex.pageManager.packageManager.showPackageNotFound(repo, name); } }; // basic repo info available? if(repoindex.client.hasBasicRepoInfo) { // yes -> can determine entry instantly determineEntry(); } else { // no -> request info, use callback to determine entry when info becomes available repoindex.client.requestBasicRepoInfo(determineEntry); } }; this.showPackageInfoForIndex = function(entryIndex, newTab) { // check whether specified entry index is valid var entry = this.entryByIndex(entryIndex); if(entry) { // show properties var setProperties = function() { // -> find info container and make info table var infoContainer = repoindex.pageManager.createPackageInfoPane(entry, newTab); infoContainer.wipeChildren(); var infoTable = repoindex.makeInfoTable(); var tb = infoTable.tbodyElement; // -> basic package info var basics = entry.info.basics ? entry.info.basics : {}; repoindex.addPackageNames(tb, "Name", [entry.name]); switch(entry.info.repo) { case "AUR": repoindex.setLink(repoindex.addField(tb, "Repository"), "AUR", "https://aur.archlinux.org/packages/" + encodeURIComponent(entry.name), window.open, "open AUR page"); break; case "core": case "extra": case "multilib": case "community": if(basics.arch) { repoindex.setLink(repoindex.addField(tb, "Repository"), entry.info.repo, "https://www.archlinux.org/packages/" + entry.info.repo + "/" + basics.arch + "/" + encodeURIComponent(entry.name), window.open, "open Arch Linux page"); break; } default: repoindex.addField(tb, "Repository", repoindex.makeStr(entry.info.repo)); } repoindex.addField(tb, "Version", repoindex.makeStr(basics.ver)); repoindex.addField(tb, "Description", repoindex.makeStr(basics.desc)); if(basics.arch) { repoindex.addField(tb, "Architecture", repoindex.makeStr(basics.arch)); } else if(basics.archs) { repoindex.addField(tb, "Architectures", repoindex.makeArray(basics.archs)); } // -> full package info var details = entry.info.details ? entry.info.details : {}; if(details.url) { repoindex.setLink(repoindex.addField(tb, "Upstream URL"), details.url, details.url, window.open); } else { repoindex.addField(tb, "Upstream URL", "unknown"); } repoindex.addField(tb, "Licenses", repoindex.makeArray(details.lic)); repoindex.addPackageNames(tb, "Groups", repoindex.pack(details.grp), repoindex.Pages.Groups); repoindex.addPackageNames(tb, "Provides", repoindex.pkgNamesFromDeps(details.prov)); repoindex.addPackageNames(tb, "Dependencies", repoindex.pkgNamesFromDeps(details.deps)); repoindex.addPackageNames(tb, "Optional deps", repoindex.pkgNamesFromDeps(details.optd)); if(details.mkd && details.mkd.length) { repoindex.addPackageNames(tb, "Make deps", repoindex.pkgNamesFromDeps(details.mkd)); } if(details.chkd && details.chkd.length) { repoindex.addPackageNames(tb, "Check deps", repoindex.pkgNamesFromDeps(details.chkd)); } if(details.requ || details.optf) { repoindex.addPackageNames(tb, "Required by", details.requ); repoindex.addPackageNames(tb, "Optional for", details.optf); } repoindex.addPackageNames(tb, "Conflicts with", repoindex.pkgNamesFromDeps(details.conf)); repoindex.addPackageNames(tb, "Replaces", repoindex.pkgNamesFromDeps(details.repl)); if(details.bav) { if(entry.info.repo !== "local") { // local repo does no provide package size repoindex.addField(tb, "Package size", repoindex.makeDataSize(details.csize)); } repoindex.addField(tb, "Install size", repoindex.makeDataSize(details.isize)); repoindex.addField(tb, "Packager", details.pack); repoindex.addField(tb, "Build date", repoindex.makeStr(basics.bdate)); if(entry.info.repo === "local") { repoindex.addField(tb, "Install date", repoindex.makeStr(details.idate)); repoindex.addField(tb, "Install reason", details.expl ? "explicitly installed" : "installed as dependency"); } repoindex.addField(tb, "Install script", repoindex.makeBool(details.scri)); repoindex.addField(tb, "Validation methods", repoindex.makeArray(details.sig, ", ")); repoindex.setTree(repoindex.addField(tb, "Package files"), repoindex.makeTree(details.files)); } if(details.sav) { if(details.main) { repoindex.addField(tb, "Maintainer", repoindex.makeStr(details.main)); } if(basics.flagdate) { repoindex.addField(tb, "Out-of-date", repoindex.makeStr(basics.flagdate)); } if(details.fsub) { repoindex.addField(tb, "First submitted", repoindex.makeStr(details.fsub)); } if(details.lmod) { repoindex.addField(tb, "Last modified", repoindex.makeStr(details.lmod)); } if(details.votes) { repoindex.addField(tb, "Votes", repoindex.makeStr(details.votes)); } } // -> update download buttons if(details.bav || details.sav) { var downloadElement = repoindex.addField(tb, "Download"); var spanElement; if(details.bav) { spanElement = document.createElement("span"); var downloadPkgParams = {repo: entry.info.repo, pkg: entry.name, down: "pkg"}; repoindex.setDownloadButton(spanElement, "package", repoindex.makeHash(repoindex.Pages.Packages, downloadPkgParams, true), function() { repoindex.pageManager.denoteHash(repoindex.Pages.Packages, downloadPkgParams); repoindex.pageManager.packageManager.showMirrorsForIndex(entryIndex); }); downloadElement.appendChild(spanElement); } if(details.srctar && typeof details.srctar === "string") { spanElement = document.createElement("span"); var downloadSrcParams = {repo: entry.info.repo, pkg: entry.name, down: "src"}; repoindex.setDownloadButton(spanElement, "source", repoindex.makeHash(repoindex.Pages.Packages, downloadSrcParams, true), function() { repoindex.pageManager.denoteHash(repoindex.Pages.Packages, downloadSrcParams); window.open("https://aur.archlinux.org" + details.srctar); }); downloadElement.appendChild(spanElement); } } infoContainer.appendChild(infoTable.tableElement); }; setProperties(); if(!entry.info.basics || !entry.info.details) { // don't have the full package info yet -> request full package info var packageSelection = {}; packageSelection[entry.info.repo] = [{index: entryIndex, name: entry.name}]; repoindex.client.requestFullPackagesInfo(packageSelection, setProperties); } // set currentInfo (the pageManager needs this value to upgrade the hash) this.currentInfo = entry.info; // ensures, that the "Package Info" box (with the properties just set) is shown repoindex.pageManager.showPackageInfo(true); } }; this.showMirrors = function(repo, name) { var determineEntry = function() { var res = repoindex.pageManager.packageManager.entries.filter(function(entry) { return entry.info.repo === repo && entry.name === name; }); // entry exists? if(res.length > 0) { // yes -> full package info available? var entry = res[0]; var showEntry = function() { repoindex.pageManager.packageManager.showMirrorsForIndex(entry.index); }; if(entry.info.details) { // yes -> show entry instantly showEntry(); } else { // no -> request full info, use callback to show entry when info becomes available var packageSelection = {}; packageSelection[entry.info.repo] = [{index: entry.index, name: entry.name}]; repoindex.client.requestFullPackagesInfo(packageSelection, showEntry); } } else { // no -> show error repoindex.pageManager.packageManager.showPackageNotFound(repo, name); } }; // basic repo info available? if(repoindex.client.hasBasicRepoInfo) { // yes -> can determine entry instantly determineEntry(); } else { // no -> request info, use callback to determine entry when info becomes available repoindex.client.requestBasicRepoInfo(determineEntry); } }; this.showMirrorsForIndex = function(entryIndex) { var entry = this.entryByIndex(entryIndex); if(entry) { var info = entry.info; repoindex.setText("title_mirror_selection", "Mirrors for package " + repoindex.escapeHtml(entry.name) + "", true); var listMirrorSelection = document.getElementById("list_mirror_selection"); listMirrorSelection.wipeChildren(); var repoEntries = repoindex.pageManager.repoManager.entries.filter(function(entry) { return entry.name === info.repo; }); var mirrorsAvailable = 0; if(repoEntries.length > 0) { var mirrors = repoEntries[0].info.servers; if(Array.isArray(mirrors) && mirrors.length > 0) { for(var i = 0; i < mirrors.length; ++i) { var liElement = document.createElement("li"); var aElement = document.createElement("a"); var url = mirrors[i] + "/" + info.details.file; aElement.appendChild(document.createTextNode(url)); aElement.href = url; aElement.onclick = function() { window.open(this.href); return false; }; liElement.appendChild(aElement); listMirrorSelection.appendChild(liElement); } mirrorsAvailable = 1; } } } if(mirrorsAvailable !== 1) { // no mirrors available? if(info.repo === "local" || info.repo === "LOCAL") { // no surprise because its an package from the local database mirrorsAvailable = -1; } else if(info.repo === "aur" || info.repo === "AUR") { // no surprise because its an AUR package mirrorsAvailable = -2; } } if(mirrorsAvailable === 1) { repoindex.setText("status_mirror_selection", "Select a mirror:"); } else if(mirrorsAvailable === -1) { repoindex.setText("status_mirror_selection", "The package belongs to the local database. Hence there are no mirrors available.", true); } else if(mirrorsAvailable === -2) { repoindex.setText("status_mirror_selection", "The package is from the Arch Linux User Repository. Hence there are no mirrors available.", true); } else { repoindex.setText("status_mirror_selection", "No mirrors available."); } $("#dlg_mirror_selection").modal("show"); }; this.showPackageNotFound = function(repo, name) { repoindex.pageManager.msgboxCritical( "Package not found", "The package " + repoindex.escapeHtml(name) + " can not be found in the repository " + repoindex.escapeHtml(repo) + ".", true); }; } return repoindex; })(repoindex || {});