-
Notifications
You must be signed in to change notification settings - Fork 23
/
Copy pathplugins.html
129 lines (121 loc) · 4.96 KB
/
plugins.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
---
layout: default
title: Endless Sky Plugin List
---
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.25/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="https://cdn.datatables.net/1.10.25/js/jquery.dataTables.js"></script>
<link rel="stylesheet" type="text/css" href="{{ 'plugins.css' | relative_url }}">
<h2 class="header">Plugin List</h2>
<p>A list of community created plugins. If you would like to add your plugin, follow the instructions on the
<a href="https://github.com/endless-sky/endless-sky/wiki/PluginRepository">wiki</a>.</p>
<div id=plugin-list><p>Loading plugins...</p></div>
<script type="text/javascript">
document.onreadystatechange = () => { if (document.readyState === 'complete') init(); };
function init() {
const headers = ['icon', 'name', 'author', 'license', 'description'];
const colOptions = [{ orderable: false, searchable: false, targets: 0 }, ];
const nodeGen = {
author: (plugin) => createByline(plugin),
description: ({ shortDescription }) => shortDescription.replace(/\n/g, ' '),
icon: ({ iconUrl, name }) => createIcon(iconUrl, name),
license: ({ license }) => createLicense(license),
name: (plugin) => createName(plugin),
};
fetch('https://raw.githubusercontent.com/endless-sky/endless-sky-plugins/master/generated/plugins.json')
.then((resp) => {
if(resp.ok) return resp.json();
throw new Error(`Failed to fetch plugin manifest: HTTP ${resp.status} ${resp.statusText}`);
})
.then((json) => {
const root = document.getElementById('plugin-list');
const table = createPluginsTable(json);
root.replaceChild(table, root.firstChild);
$(table).DataTable({
columnDefs: colOptions,
order: [[1, 'asc']],
pageLength: 50,
});
})
.catch((err) => {
const node = document.getElementById('plugin-list');
node.id += '-error';
node.firstElementChild.innerHTML = '<span class="centered">:warning: There was a problem displaying the list of plugins here. :warning:</span><br>'
+ 'Don\'t worry, you can visit the <a href="https://github.com/endless-sky/endless-sky-plugins">Endless Sky plugins</a> repository directly. '
+ 'Please consider reporting this error on <a href="{{ site.github.repository_url }}">GitHub</a> or <a href="https://discord.gg/ZeuASSx">Discord</a>:';
const pre = document.createElement('pre');
const stack = !('stack' in err) ? '' : err.stack.split(/\n/).filter((t) => t.trim() && !t.includes(err.message))
.map((t) => ` at ${t.trim().replace('at ', '')}`).join('\n')
.replace(err.message, ''); // Chromium includes the message in the stack, while Firefox does not.
pre.textContent = `${err}\n${stack}`;
node.append(pre);
});
function createCell(type, classname, ...stringOrNodes) {
const cell = document.createElement(type);
cell.classList.add(classname);
cell.append(...stringOrNodes);
return cell;
}
function createRow(pluginData) {
const row = document.createElement('tr');
const cells = headers.map((column) => {
const fn = nodeGen[column] || (() => '');
const stringOrNodes = fn(pluginData);
return stringOrNodes ? createCell('td', column, ...stringOrNodes) : createCell('td', '(not provided)');
});
row.append(...cells);
return row;
}
function createPluginsTable(pluginList) {
const table = document.createElement('table');
table.id = 'plugins-table';
const header = document.createElement('thead');
const headerRow = document.createElement('tr');
headerRow.append(...headers.map((name) => {
const cell = document.createElement('th');
cell.textContent = name.charAt(0).toUpperCase() + name.slice(1);
return cell;
}));
header.appendChild(headerRow);
table.appendChild(header);
const body = document.createElement('tbody');
body.append(...pluginList.map(createRow));
table.appendChild(body);
return table;
}
function createIcon(url = '{{ "/images/unknown-outfit.png" | absolute_url }}', name) {
const img = document.createElement('img');
img.src = url;
img.decoding = 'async';
img.loading = 'lazy';
img.alt = `Icon for plugin ${name}`;
img.classList.add('plugin-icon', 'centered');
return [img];
}
function createLicense(spdx = '') {
if (!spdx) {
return ['All Rights Reserved by author(s)'];
}
const link = document.createElement('a');
link.href = `https://spdx.org/licenses/${spdx}.html`;
link.text = spdx;
return [link];
}
function createName({ name, homepage, version }) {
const link = document.createElement('a');
link.href = homepage;
link.text = name;
link.classList.add('plugin-name');
if (version.length === 40) {
version = version.substring(0, 7);
}
return [link, document.createElement('br'), `Version: ${version}`];
}
function createByline({ author, authors }) {
if (author) return author;
if (Array.isArray(authors)) return authors[0];
if (typeof authors === 'string') return authors.split(',')[0];
return '(unknown author)';
}
}
</script>