on master help sign in
cleanup
commit1588aa43a0d200e484a27372559af7fefda985a3 authorckipp01 <ckipp@pm.me> dateSat 10 Aug 2019, 11:53 (7 years ago) parentf181ace
6 files changed+164−428
links/main.css+56−64 links/main2.css−84 scripts/wiki.js+106−122 scripts/wiki2.js−136 wiki.html+2−2 wiki2.html−20
links/main.css+56−64
@@ -1,39 +1,39 @@
11* { margin:0;padding:0;border:0;outline:0;text-decoration:none;font-weight:inherit;font-style:inherit;color:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;list-style:none;border-collapse:collapse;border-spacing:0; -webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
22
33body { background:#f4f4f4; padding:0px; margin:0px; }
4−body > div { display:block; background: #111;min-height: calc(100vh - 60px);width: calc(100vw - 60px);margin: 15px;color: #333;padding: 15px;font-family:'input_mono_regular', 'Monospaced','Courier New',courier;font-size:11px; position: relative; border-radius: 2px; color:white; overflow: hidden;}
5−body > div > ul { max-width: 800px; padding-bottom: 15px;margin-bottom:15px; overflow: hidden;}
6−body div p { display:block; padding:0px 5px; line-height: 20px; max-width: 600px}
7−body div p a { text-decoration: underline; cursor: pointer;}
8−body div p a:hover { text-decoration: underline; }
4+body > div { background: #111; min-height: calc(100vh - 60px); width: calc(100vw - 60px); margin: 15px; padding: 15px; font-family:'input_mono_regular', 'Monospaced','Courier New',courier; font-size:11px; color:white; position: relative; }
5+body > div > ul { padding-bottom: 15px; margin-bottom:15px; }
6+body div p { display:block; padding:0px 5px; line-height: 20px;}
7+body footer { border-top: 2px solid white; padding-top: 15px; margin-top: 15px;}
8+body footer a { text-decoration: underline; }
99body strong { font-weight: normal; font-family: 'input_mono_medium' }
10−body div p.readme { max-width:500px; }
11−body .col3 { columns:3; }
1210body .selected { background: white; color:black; }
1311
14−body #sidebar { position: absolute;top: 0px;right: 0px;padding: 15px;width: 200px; overflow: hidden;}
15−body #sidebar > * { border-bottom: 0px; line-height: 16px; padding-bottom: 0px }
16−body #sidebar ul { margin-bottom: 15px }
17−body #sidebar > * li { text-transform: lowercase; }
18−body #sidebar > * li:hover { cursor: pointer; }
19−body #sidebar > * li span.right { color:#555; float:right; }
20−body #sidebar > * li span.right:after { content: " msgs"; }
21−body #sidebar #channels li:before, body #sidebar #categories li:before { content:'/'; }
22−body #sidebar #users li:before { content:'@'; }
23−body #footer { padding-left: 60px; background-image: url(../icon.white.svg); background-size: 40px; background-repeat: no-repeat; background-position: 0px 10px; border-top: 2px solid white; padding-top: 15px; margin-top: 15px; max-width: calc(100% - 300px); min-height: 45px; line-height: 15px;}
24−
25−@media only screen and (min-width:200px) and (max-width: 800px) {
26− body #hallway #sidebar { position: absolute;top: 0px;right: 0px;padding: 15px;width: 200px;display: none;background-color: #000; }
27− body #hallway #sidebar #channels { margin-top: 30px; }
28−}
29−
30−/* Hallway */
12+/* portal */
13+body #portal main,
14+body #portal footer { max-width: 800px; }
15+body #portal #icon { display: block; width: 30px; height: 30px; background-image: url(../icon.white.svg); background-size: cover; background-repeat: no-repeat; position: absolute; bottom: 15px; right:15px; background-position: center; padding:0px }
16+body #portal ul { columns:1; }
17+body #portal ul li { display:block; padding-left:5px; text-overflow: ellipsis; text-transform: lowercase;}
18+body #portal ul li:before { content: attr(id) ")"; }
19+body #portal ul li[data-type]::after { content:"<" attr(data-type) ">"; color:#555; }
20+body #portal ul li a { line-height: 20px; padding:0px 5px; text-decoration: none;}
21+body #portal ul li a:visited { color:#ccc; text-decoration: none;}
22+body #portal ul li a:hover { text-decoration: underline; }
3123
32−body #hallway #entries { width: calc(100vw - 300px) !important; }
24+body aside { min-width: 200px; padding: 0 15px; line-height: 16px; display: none; }
25+body aside ul { margin-bottom: 15px; }
26+body aside #channels li:before, body #sidebar #categories li:before { content:'/'; }
27+body aside #users li:before { content:'@'; }
28+body aside span.right { color: #555; float: right; }
29+body aside li { text-transform: lowercase; cursor: pointer; }
3330
34−body #hallway #pagination { margin: 10px; text-align: center; }
35−body #hallway #pagination span { padding: 3px; margin: 2px; cursor: pointer; }
31+/* hallway */
3632
33+body #hallway #entries { display: flex; margin-top: 35px; }
34+body #hallway #entries > div { flex-grow: 1; }
35+body #hallway #showbar { position: absolute;top: 0px;width: 92%;height: 50px; background-image: url("data:image/svg+xml; utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><path d='M11,4 L11,18 M4,4 L 4,18 M18,4 L18,18' stroke='%23555' fill='none' stroke-width='2' stroke-linecap='round'/></svg>");background-repeat: no-repeat;background-position: right;background-size: 25px; }
36+body #hallway #hidebar { position: absolute;top: 0px;width: 100%;height: 50px;background-image: url("data:image/svg+xml; utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><path d='M5,5 L17,17 M17,5 L5,17' stroke='%23555' fill='none' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");background-repeat: no-repeat;background-position: left;background-size: 25px; }
3737body #hallway .entry { line-height: 16px; display: block; position: relative; padding-left:100px; }
3838body #hallway .entry .date { color: #555;display: block;float:right; margin-left:20px; padding-bottom: 16px;}
3939body #hallway .entry .author { font-family: 'input_mono_medium'; position: absolute;left: 0px; }
@@ -48,45 +48,37 @@ body #hallway .entry.highlight .author { color:#555; }
4848body #hallway .entry:hover .author { color:#ccc; }
4949body #hallway .entry:hover .date { color:#ccc; }
5050body #hallway .entry:hover .body { color:#ccc; border-bottom-color: #555 }
51−body #hallway ul { max-width: 100%; }
52−body #hallway ul li:last-child { border-bottom:0px; }
51+body #hallway #footer { padding-left: 60px; background-image: url(../icon.white.svg); background-size: 40px; background-repeat: no-repeat; background-position: 0px 10px; border-top: 2px solid white; padding-top: 20px; margin-top: 15px; max-width: calc(100% - 300px); min-height: 45px; line-height: 15px;}
5352
54−@media only screen and (min-width:200px) and (max-width: 800px) {
55− body #hallway #entries { width: 100% !important;margin-top: 30px; }
56− body #hallway #showbar { position: absolute;top: 0px;width: 92%;height: 50px; background-image: url("data:image/svg+xml; utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><path d='M11,4 L11,18 M4,4 L 4,18 M18,4 L18,18' stroke='%23555' fill='none' stroke-width='2' stroke-linecap='round'/></svg>");background-repeat: no-repeat;background-position: right;background-size: 25px; }
57− body #hallway #hidebar { position: absolute;top: 0px;width: 100%;height: 50px;background-image: url("data:image/svg+xml; utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><path d='M5,5 L17,17 M17,5 L5,17' stroke='%23555' fill='none' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");background-repeat: no-repeat;background-position: left;background-size: 25px; }
58−}
59−
60−/* Portal */
53+body #hallway #pagination { margin: 10px; text-align: center; }
54+body #hallway #pagination span { padding: 3px; margin: 2px; cursor: pointer; }
6155
62−body #portal #icon { display: block;width: 30px;height: 30px;background-image: url(../icon.white.svg);background-size: cover;background-repeat: no-repeat;position: absolute;bottom: 15px;right:15px;background-position: center;padding:0px }
63−body #portal ul { columns:3; }
64−body #portal ul li { display:block; padding-left:5px; text-overflow: ellipsis; text-transform: lowercase;}
65−body #portal ul li:before { content: attr(id) ")"; }
66−body #portal ul li[data-type]::after { content:"<" attr(data-type) ">"; color:#555; }
67−body #portal ul li a { line-height: 20px; padding:0px 5px; text-decoration: none;}
68−body #portal ul li a:visited { color:#ccc; text-decoration: none;}
69−body #portal ul li a:hover { text-decoration: underline; }
56+/* wiki */
57+body #wiki { background: #ccc; color:#333; }
58+body #wiki main { display: flex; }
59+body #wiki main { flex: 1; }
60+body #wiki main { max-width: calc(100% - 230px); }
61+body #wiki main h1 { font-size: 1.3em; margin: 5px 0; font-weight: bold; }
62+body #wiki main div.related { border-bottom: 1px solid white; margin-bottom: 10px; }
63+body #wiki #main { width: 100%; }
64+body #wiki #main ul li { line-height: 15px; }
65+body #wiki aside { min-width: 220px; }
66+body #wiki aside { overflow-y: scroll; height: calc(100% - 15px); position: absolute; right: 0;}
67+body #wiki aside a { display: inline-block; width: 135px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding: 7px; }
68+body #wiki aside li { line-height: 7px; }
69+body #wiki aside li:before { display: none; }
70+body #wiki aside a:before { content: '/'; }
71+body #wiki aside a:after { content: attr(data-msgs) " msgs"; position: absolute; right: 20px; color:#555; }
72+body #wiki ul.term { margin-bottom: 15px; }
73+body #wiki ul.term li.name { margin-bottom: 5px; }
74+body #wiki #footer { padding-left: 60px; background-image: url(../icon.white.svg); background-size: 40px; background-repeat: no-repeat; background-position: 0px 10px; border-top: 2px solid white; padding-top: 22px; margin-top: 15px; max-width: calc(100% - 300px); min-height: 45px; line-height: 15px;}
7075
71−@media (max-width: 730px) {
72− body #portal ul li:before { display: none }
73−}
74−@media (max-width: 630px) {
75− body #portal ul { columns: 2 !important; }
76− body #portal ul li:before { display: none }
77−}
78−@media (max-width: 530px) {
79− body #portal ul { columns: 1 !important; }
80− body #portal ul li:before { display: inline }
76+@media (min-width: 630px) {
77+ body aside { display: block; }
78+ body #portal ul { columns: 3;}
79+ body #hallway #entries { margin-top: 0; }
80+ body #hallway #showbar { display: none; }
81+ body #hallway #hidebar { display: none; }
82+ body #wiki footer { margin-right: 225px; }
8183}
8284
83−/* Wiki */
84−
85−body #wiki { background: #ccc; color:#333; }
86−body #wiki #entry { max-width: calc(100% - 230px); margin-bottom: 30px; line-height: 15px }
87−body #wiki #entry a { text-decoration: underline; }
88−body #wiki ul.term { border-bottom: 0px; margin-bottom: 0px; padding-bottom: 0px}
89−body #wiki ul.term li { margin-bottom: 5px }
90−body #wiki ul.term li.name { margin-bottom: 5px }
91−body #wiki ul.term li a.author { color:#555; text-decoration: none !important; }
92−
links/main2.cssdeleted−84
@@ -1,84 +0,0 @@
1−* { margin:0;padding:0;border:0;outline:0;text-decoration:none;font-weight:inherit;font-style:inherit;color:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;list-style:none;border-collapse:collapse;border-spacing:0; -webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;}
2−
3−body { background:#f4f4f4; padding:0px; margin:0px; }
4−body > div { background: #111; min-height: calc(100vh - 60px); width: calc(100vw - 60px); margin: 15px; padding: 15px; font-family:'input_mono_regular', 'Monospaced','Courier New',courier; font-size:11px; color:white; position: relative; }
5−body > div > ul { padding-bottom: 15px; margin-bottom:15px; }
6−body div p { display:block; padding:0px 5px; line-height: 20px;}
7−body footer { border-top: 2px solid white; padding-top: 15px; margin-top: 15px;}
8−body footer a { text-decoration: underline; }
9−body strong { font-weight: normal; font-family: 'input_mono_medium' }
10−body .selected { background: white; color:black; }
11−
12−/* portal */
13−body #portal main,
14−body #portal footer { max-width: 800px; }
15−body #portal #icon { display: block; width: 30px; height: 30px; background-image: url(../icon.white.svg); background-size: cover; background-repeat: no-repeat; position: absolute; bottom: 15px; right:15px; background-position: center; padding:0px }
16−body #portal ul { columns:1; }
17−body #portal ul li { display:block; padding-left:5px; text-overflow: ellipsis; text-transform: lowercase;}
18−body #portal ul li:before { content: attr(id) ")"; }
19−body #portal ul li[data-type]::after { content:"<" attr(data-type) ">"; color:#555; }
20−body #portal ul li a { line-height: 20px; padding:0px 5px; text-decoration: none;}
21−body #portal ul li a:visited { color:#ccc; text-decoration: none;}
22−body #portal ul li a:hover { text-decoration: underline; }
23−
24−body aside { min-width: 200px; padding: 0 15px; line-height: 16px; display: none; }
25−body aside ul { margin-bottom: 15px; }
26−body aside #channels li:before, body #sidebar #categories li:before { content:'/'; }
27−body aside #users li:before { content:'@'; }
28−body aside span.right { color: #555; float: right; }
29−body aside li { text-transform: lowercase; cursor: pointer; }
30−
31−/* hallway */
32−
33−body #hallway #entries { display: flex; margin-top: 35px; }
34−body #hallway #entries > div { flex-grow: 1; }
35−body #hallway #showbar { position: absolute;top: 0px;width: 92%;height: 50px; background-image: url("data:image/svg+xml; utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><path d='M11,4 L11,18 M4,4 L 4,18 M18,4 L18,18' stroke='%23555' fill='none' stroke-width='2' stroke-linecap='round'/></svg>");background-repeat: no-repeat;background-position: right;background-size: 25px; }
36−body #hallway #hidebar { position: absolute;top: 0px;width: 100%;height: 50px;background-image: url("data:image/svg+xml; utf8,<svg xmlns='http://www.w3.org/2000/svg' width='22' height='22'><path d='M5,5 L17,17 M17,5 L5,17' stroke='%23555' fill='none' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>");background-repeat: no-repeat;background-position: left;background-size: 25px; }
37−body #hallway .entry { line-height: 16px; display: block; position: relative; padding-left:100px; }
38−body #hallway .entry .date { color: #555;display: block;float:right; margin-left:20px; padding-bottom: 16px;}
39−body #hallway .entry .author { font-family: 'input_mono_medium'; position: absolute;left: 0px; }
40−body #hallway .entry .body { display: block;border-bottom: 1px solid #333;padding-bottom: 10px;margin-bottom: 10px; }
41−body #hallway .entry .body a { text-decoration: underline; }
42−body #hallway .entry .body .channel { display: inline-block;border-radius: 1px;font-family: 'input_mono_medium';color: #777; }
43−body #hallway .entry .body .user { display: inline-block;border-radius: 1px;font-family: 'input_mono_medium';color: #777; }
44−body #hallway .entry .body .user.local::before { content:'@';color: #777; }
45−body #hallway .entry .body .user.external::before { content:'^';color: #777; }
46−body #hallway .entry .body .tag { display: inline-block;border-radius: 1px;font-family: 'input_mono_medium';color: #777; }
47−body #hallway .entry.highlight .author { color:#555; }
48−body #hallway .entry:hover .author { color:#ccc; }
49−body #hallway .entry:hover .date { color:#ccc; }
50−body #hallway .entry:hover .body { color:#ccc; border-bottom-color: #555 }
51−body #hallway #footer { padding-left: 60px; background-image: url(../icon.white.svg); background-size: 40px; background-repeat: no-repeat; background-position: 0px 10px; border-top: 2px solid white; padding-top: 20px; margin-top: 15px; max-width: calc(100% - 300px); min-height: 45px; line-height: 15px;}
52−
53−body #hallway #pagination { margin: 10px; text-align: center; }
54−body #hallway #pagination span { padding: 3px; margin: 2px; cursor: pointer; }
55−
56−/* wiki */
57−body #wiki { background: #ccc; color:#333; }
58−body #wiki main { display: flex; }
59−body #wiki main { flex: 1; }
60−body #wiki main { max-width: calc(100% - 230px); }
61−body #wiki main h1 { font-size: 1.3em; margin: 5px 0; font-weight: bold; }
62−body #wiki main div.related { border-bottom: 1px solid white; margin-bottom: 10px; }
63−body #wiki #main { width: 100%; }
64−body #wiki #main ul li { line-height: 15px; }
65−body #wiki aside { min-width: 220px; }
66−body #wiki aside { overflow-y: scroll; height: calc(100% - 15px); position: absolute; right: 0;}
67−body #wiki aside a { display: inline-block; width: 135px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; padding: 7px; }
68−body #wiki aside li { line-height: 7px; }
69−body #wiki aside li:before { display: none; }
70−body #wiki aside a:before { content: '/'; }
71−body #wiki aside a:after { content: attr(data-msgs) " msgs"; position: absolute; right: 20px; color:#555; }
72−body #wiki ul.term { margin-bottom: 15px; }
73−body #wiki ul.term li.name { margin-bottom: 5px; }
74−body #wiki #footer { padding-left: 60px; background-image: url(../icon.white.svg); background-size: 40px; background-repeat: no-repeat; background-position: 0px 10px; border-top: 2px solid white; padding-top: 22px; margin-top: 15px; max-width: calc(100% - 300px); min-height: 45px; line-height: 15px;}
75−
76−@media (min-width: 630px) {
77− body aside { display: block; }
78− body #portal ul { columns: 3;}
79− body #hallway #entries { margin-top: 0; }
80− body #hallway #showbar { display: none; }
81− body #hallway #hidebar { display: none; }
82− body #wiki footer { margin-right: 225px; }
83−}
84−
scripts/wiki.js+106−122
@@ -1,152 +1,136 @@
11'use strict'
2−function Wiki (sites) {
3− const feeds = {}
4− this.sites = sites
5− this._el = document.createElement('div')
6− this._el.id = 'wiki'
7− this._sidebar = document.createElement('div')
8− this._sidebar.id = 'sidebar'
9− this._categories = document.createElement('ul')
10− this._categories.id = 'categories'
11− this._entry = document.createElement('div')
12− this._entry.id = 'entry'
13−
14− this._footer = document.createElement('p')
15− this._footer.id = 'footer'
16− this._footer.innerHTML = `The <strong>Wiki</strong> is a decentralized encyclopedia, to join the conversation, add a <a href="https://github.com/XXIIVV/webring#joining-the-wiki">wiki:</a> field to your entry in the <a href="https://github.com/XXIIVV/Webring/">webring</a>.`
17−
18− this.loc = ''
19− this.byName = {}
20− this.byCat = {}
21− this.byAuthor = {}
22−
23− this.install = (host) => {
24− this._el.appendChild(this._entry)
25− this._sidebar.appendChild(this._categories)
26− this._el.appendChild(this._sidebar)
27− this._el.appendChild(this._footer)
28− host.appendChild(this._el)
29− this.fetch()
30− }
31−
32− this.start = () => {
33− this._entry.innerHTML = 'Loading..'
34− }
352
36− this.refresh = () => {
37− // Main
38− if (this.loc) {
39− if (this.byCat[this.loc]) {
40− const formatHtml = (entries, entry) => `${entries} ${this.templateTerm(entry.name, this.byName[entry.name])}<br />`
41− const html = this.byCat[this.loc].reduce(formatHtml, '')
42− this._entry.innerHTML = html
43− } else if (this.byName[this.loc]) {
44− const html = `${this.templateTerm(this.loc, this.byName[this.loc])}<br />${this.templateRelated(this.loc)}`
45− this._entry.innerHTML = html
46− } else {
47− const html = `Unknown: ${this.loc}. Return <a href='#'>home</a>, or try a <a href='${this.random()}'>random page</a>.`
48− this._entry.innerHTML = html
49− }
3+const Wiki = sites => {
4+ const entries = {}
5+ const main = document.getElementById('main')
6+ const aside = document.getElementById('aside')
7+ const authors = new Set()
8+ const terms = new Set()
9+
10+ const storeEntry = (author, url, parent, cat, entry) => {
11+ if (!(parent in entries)) {
12+ entries[parent] = {}
13+ entries[parent][cat] = [{ entry, author, url }]
14+ } else if (!(cat in entries[parent])) {
15+ entries[parent][cat] = [{ entry, author, url }]
5016 } else {
51− this._entry.innerHTML = `Click a /topic to get started, or try a <a href='#${this.random()}'>random page</a>.<br />The wiki contains ${Object.keys(this.byName).length} terms, in ${Object.keys(this.byCat).length} categories, by ${Object.keys(this.byAuthor).length} authors.`
17+ entries[parent][cat].push({ entry, author, url })
5218 }
53− // Sidebar
54− this._categories.innerHTML = Object.keys(this.byCat).reduce((acc, id) =>
55− { return this.byCat[id].length > 5
56− ? `${acc}<li ${wiki.at(id) ? 'class="selected"' : ''}>
57− <a href='#${id}' data-msgs='${this.byCat[id].length}'>${id}</a>
58− </li>`
59− : acc
60− } , `<li ${wiki.at() ? 'class="selected"' : ''}>
61− <a href='#' data-msgs='${Object.keys(this.byName).length}'>home</a>
62− </li>`
63− )
19+ terms.add(cat)
20+ authors.add(author)
6421 }
6522
66− this.go = () => {
67− this.loc = decodeURIComponent( window.location.hash.substr(1) ).toUpperCase()
68− this.refresh()
23+ const storeEntries = (author, url, parent, entries) => {
24+ Array.isArray(entries)
25+ ? storeEntry(author, url, parent, 'list-definitions', entries)
26+ : Object.keys(entries).forEach(entry => storeEntry(author, url, parent, entry, entries[entry]))
6927 }
7028
71− this.at = (q = '') => {
72− return this.loc.toUpperCase() === q.toUpperCase() || (this.cat(this.loc).toUpperCase() === q.toUpperCase() && q !== '')
29+ const transform = (author, url, ndtl) => {
30+ Object.keys(ndtl).forEach(cat => storeEntries(author, url, cat, ndtl[cat]))
7331 }
7432
75− this.random = () => {
76− const keys = Object.keys(this.byCat)
77− return keys[Math.floor(Math.random() * keys.length)]
33+ const parse = (site, content) => {
34+ console.log('Wiki', 'Parsing ' + site.wiki)
35+ const ndtl = indental(content)
36+ transform(site.author, site.url, ndtl)
7837 }
7938
80− this.related = (name) => {
81− return this.byCat[this.cat(name)]
82− }
39+ const selected = (key, category) => key.toLowerCase() === category.toLowerCase()
40+ ? 'selected'
41+ : ''
8342
84− this.cat = (name) => {
85− return this.byName[name] ? this.byName[name][0].cat : ''
43+ const formatSideBarCat = (key, entries) => (currentHtml, cat) => {
44+ const catLength = Object.keys(entries[cat]).length
45+ const newHtml = `<li class='${selected(key, cat)}'}'>
46+ <a href='#${cat}' data-msgs='${catLength}'>${cat.toLowerCase()}</a>
47+ </li>`
48+ return `${currentHtml}${newHtml}`
8649 }
8750
88− this.templateRelated = (name) => {
89− const relatedWords = this.related(name)
90− const html = `<ul class='col3'>${relatedWords.reduce( (acc, item, id) =>
91− { return `${acc}<li ${wiki.at(item.name) ? 'class="selected"' : ''}>
92− <a href='#${item.name.toLowerCase()}'>${item.name.toLowerCase()}</a>
93− </li>`
94− }, '') }
95− </ul>`
96− return html
97− }
51+ const formatEntry = (definitions, definition) => {
52+ const formatEntryList = entryList => entryList.reduce((items, item) => `${items}<li>${item}</li>`, '')
9853
99− this.templateTerm = (name, entries) => {
100− const formatEntry = (acc, entry) => {
101− if (typeof entry.value === 'string') {
102− return `${acc}<li>${entry.value}<a class='author' target='_blank' href='${entry.origin.url}'> — @${entry.origin.author}</a></li>`
103− } else {
104− const listItems = entry.value.reduce((items, item) => `${items}<li>${item}</li>`, '')
105− return `${acc}<li><ul>${listItems}<a class='author' target='_blank' href='${entry.origin.url}'> — @${entry.origin.author}</a></ul></li>`
106− }
107− }
54+ const newHtml = typeof definition.entry === 'string'
55+ ? `<li>${definition.entry}
56+ <a class='author' target='_blank' href='${definition.url}'> - @${definition.author}</a>
57+ </li>`
58+ : `<li><ul>${formatEntryList(definition.entry)}
59+ <a class='author' target='_blank' href='${definition.url}'> — @${definition.author}</a>
60+ </ul></li>`
10861
109− const htmlEntries = entries.reduce(formatEntry, '')
110− return `<ul class="term"><li class="name"><strong>${name.toLowerCase()}</strong></li>${htmlEntries}</ul>`
62+ return `${definitions}${newHtml}`
11163 }
11264
113− this.fetch = () => {
114− console.log('Wiki', 'Fetching..')
115− for (const site of sites) {
116− if (!site.wiki || !site.author) { continue }
117− fetch(site.wiki, { cache: 'no-store' }).then(x => x.text()).then((content) => {
118− this.parse(site, content)
119− this.refresh(feeds)
120− }).catch((err) => {
121− console.warn(`${site.wiki}`, err)
122− })
123− }
65+ const formatEntries = entries => (currentHtml, category) => {
66+ const definitions = entries[category].reduce(formatEntry, '')
67+ const title = category === 'list-definitions'
68+ ? ''
69+ : `<li class='name'><strong>${category.toLowerCase()}</strong></li>`
70+ return `${currentHtml}<ul class='term'>${title}${definitions}</ul>`
12471 }
12572
126− this.add = (name, value, cat, origin) => {
127− this.byName[name] = this.byName[name] || []
128− this.byName[name].push({ name, value, cat, origin })
73+ const findRelated = key => {
74+ const searchOtherCategories = entry => {
75+ return Object.keys(entries)
76+ .filter(category => Object.keys(entries[category]).some(otherCat => otherCat === entry))
77+ }
12978
130− this.byCat[cat] = this.byCat[cat] || []
131− this.byCat[cat].push({ name, value, cat, origin })
79+ const foundMatches = Object.keys(entries[key])
80+ .filter(entry => entry !== 'list-definitions')
81+ .map(searchOtherCategories)
82+ const flattened = [].concat.apply([], foundMatches)
83+ return Array.from(new Set(flattened)).filter(related => related !== key)
84+ }
13285
133− this.byAuthor[origin.author] = this.byAuthor[origin.author] || []
134− this.byAuthor[origin.author].push({ name, value, cat, origin })
86+ const formatRelated = (allRelated, relatedCategory) => {
87+ const newHtml = `<span><a href='#${relatedCategory}'>/${relatedCategory.toLowerCase()}</a> </span>`
88+ return `${allRelated}${newHtml}`
13589 }
13690
137− this.parse = (site, content) => {
138− console.log('Wiki', 'Parsing ' + site.wiki)
139− const cats = indental(content)
140− for (const cat in cats) {
141− const terms = cats[cat]
142− for (const name in terms) {
143− this.add(name, terms[name], cat, site)
144− }
91+ const refresh = key => {
92+ if (key) {
93+ if (entries[key] === undefined) return
94+ const items = Object.keys(entries[key]).sort().reduce(formatEntries(entries[key]), '')
95+ const relatedCategories = findRelated(key)
96+ const relatedHtml = relatedCategories.length > 0
97+ ? relatedCategories.reduce(formatRelated, 'Related categories: ')
98+ : ''
99+ main.innerHTML = `<div class='related'><h1>${key}</h1>${relatedHtml}</div>${items}`
100+ } else {
101+ const html = `Click a /topic to get started, or try a random page`
102+ const stats = `The wiki contains ${terms.size} terms in ${Object.keys(entries).length} categories, from ${authors.size} authors.`
103+ main.innerHTML = `${html}<br />${stats}`
145104 }
105+
106+ const homeCat = `<li class='${selected(key, '')}'>
107+ <a href='#' data-msgs='${terms.size}'>home</a>
108+ </li>`
109+ const cats = Object.keys(entries).sort().reduce(formatSideBarCat(key, entries), homeCat)
110+ aside.innerHTML = `<ul>${cats}</ul>`
146111 }
147112
148− String.prototype.toUrl = function () { return this.toLowerCase().replace(/ /g, '+').replace(/[^0-9a-z+:\-./~]/gi, '').trim() }
113+ return {
114+ initialize: hash => {
115+ console.log('Wiki', 'Fetching...')
116+ sites.filter(site => site.wiki && site.author).forEach(site => {
117+ fetch(site.wiki, { cache: 'no-store' }).then(x => x.text()).then(content => {
118+ parse(site, content)
119+ refresh(stripHash(hash))
120+ }).catch((err) => {
121+ console.warn(`${site.wiki}`, err)
122+ })
123+ })
124+ },
125+ refresh: key => { refresh(key) }
126+ }
127+}
149128
150− window.onload = this.go
151− window.onhashchange = this.go
129+const stripHash = hash => {
130+ const decoded = decodeURIComponent(hash)
131+ return decoded.charAt(0) === '#' ? decoded.substring(1) : decoded
152132}
133+
134+window.addEventListener('hashchange', () => {
135+ wiki.refresh(stripHash(window.location.hash).toUpperCase())
136+})
scripts/wiki2.jsdeleted−136
@@ -1,136 +0,0 @@
1−'use strict'
2−
3−const Wiki = sites => {
4− const entries = {}
5− const main = document.getElementById('main')
6− const aside = document.getElementById('aside')
7− const authors = new Set()
8− const terms = new Set()
9−
10− const storeEntry = (author, url, parent, cat, entry) => {
11− if (!(parent in entries)) {
12− entries[parent] = {}
13− entries[parent][cat] = [{ entry, author, url }]
14− } else if (!(cat in entries[parent])) {
15− entries[parent][cat] = [{ entry, author, url }]
16− } else {
17− entries[parent][cat].push({ entry, author, url })
18− }
19− terms.add(cat)
20− authors.add(author)
21− }
22−
23− const storeEntries = (author, url, parent, entries) => {
24− Array.isArray(entries)
25− ? storeEntry(author, url, parent, 'list-definitions', entries)
26− : Object.keys(entries).forEach(entry => storeEntry(author, url, parent, entry, entries[entry]))
27− }
28−
29− const transform = (author, url, ndtl) => {
30− Object.keys(ndtl).forEach(cat => storeEntries(author, url, cat, ndtl[cat]))
31− }
32−
33− const parse = (site, content) => {
34− console.log('Wiki', 'Parsing ' + site.wiki)
35− const ndtl = indental(content)
36− transform(site.author, site.url, ndtl)
37− }
38−
39− const selected = (key, category) => key.toLowerCase() === category.toLowerCase()
40− ? 'selected'
41− : ''
42−
43− const formatSideBarCat = (key, entries) => (currentHtml, cat) => {
44− const catLength = Object.keys(entries[cat]).length
45− const newHtml = `<li class='${selected(key, cat)}'}'>
46− <a href='#${cat}' data-msgs='${catLength}'>${cat.toLowerCase()}</a>
47− </li>`
48− return `${currentHtml}${newHtml}`
49− }
50−
51− const formatEntry = (definitions, definition) => {
52− const formatEntryList = entryList => entryList.reduce((items, item) => `${items}<li>${item}</li>`, '')
53−
54− const newHtml = typeof definition.entry === 'string'
55− ? `<li>${definition.entry}
56− <a class='author' target='_blank' href='${definition.url}'> - @${definition.author}</a>
57− </li>`
58− : `<li><ul>${formatEntryList(definition.entry)}
59− <a class='author' target='_blank' href='${definition.url}'> — @${definition.author}</a>
60− </ul></li>`
61−
62− return `${definitions}${newHtml}`
63− }
64−
65− const formatEntries = entries => (currentHtml, category) => {
66− const definitions = entries[category].reduce(formatEntry, '')
67− const title = category === 'list-definitions'
68− ? ''
69− : `<li class='name'><strong>${category.toLowerCase()}</strong></li>`
70− return `${currentHtml}<ul class='term'>${title}${definitions}</ul>`
71− }
72−
73− const findRelated = key => {
74− const searchOtherCategories = entry => {
75− return Object.keys(entries)
76− .filter(category => Object.keys(entries[category]).some(otherCat => otherCat === entry))
77− }
78−
79− const foundMatches = Object.keys(entries[key])
80− .filter(entry => entry !== 'list-definitions')
81− .map(searchOtherCategories)
82− const flattened = [].concat.apply([], foundMatches)
83− return Array.from(new Set(flattened)).filter(related => related !== key)
84− }
85−
86− const formatRelated = (allRelated, relatedCategory) => {
87− const newHtml = `<span><a href='#${relatedCategory}'>/${relatedCategory.toLowerCase()}</a> </span>`
88− return `${allRelated}${newHtml}`
89− }
90−
91− const refresh = key => {
92− if (key) {
93− if (entries[key] === undefined) return
94− const items = Object.keys(entries[key]).sort().reduce(formatEntries(entries[key]), '')
95− const relatedCategories = findRelated(key)
96− const relatedHtml = relatedCategories.length > 0
97− ? relatedCategories.reduce(formatRelated, 'Related categories: ')
98− : ''
99− main.innerHTML = `<div class='related'><h1>${key}</h1>${relatedHtml}</div>${items}`
100− } else {
101− const html = `Click a /topic to get started, or try a random page`
102− const stats = `The wiki contains ${terms.size} terms in ${Object.keys(entries).length} categories, from ${authors.size} authors.`
103− main.innerHTML = `${html}<br />${stats}`
104− }
105−
106− const homeCat = `<li class='${selected(key, '')}'>
107− <a href='#' data-msgs='${terms.size}'>home</a>
108− </li>`
109− const cats = Object.keys(entries).sort().reduce(formatSideBarCat(key, entries), homeCat)
110− aside.innerHTML = `<ul>${cats}</ul>`
111− }
112−
113− return {
114− initialize: hash => {
115− console.log('Wiki', 'Fetching...')
116− sites.filter(site => site.wiki && site.author).forEach(site => {
117− fetch(site.wiki, { cache: 'no-store' }).then(x => x.text()).then(content => {
118− parse(site, content)
119− refresh(stripHash(hash))
120− }).catch((err) => {
121− console.warn(`${site.wiki}`, err)
122− })
123− })
124− },
125− refresh: key => { refresh(key) }
126− }
127−}
128−
129−const stripHash = hash => {
130− const decoded = decodeURIComponent(hash)
131− return decoded.charAt(0) === '#' ? decoded.substring(1) : decoded
132−}
133−
134−window.addEventListener('hashchange', () => {
135− wiki.refresh(stripHash(window.location.hash).toUpperCase())
136−})
wiki.html+2−2
@@ -4,8 +4,8 @@
44 <meta charset="utf-8">
55 <meta name="viewport" content="width=device-width, initial-scale=1.0">
66 <link rel="stylesheet" type="text/css" href="links/fonts.css"/>
7− <link rel="stylesheet" type="text/css" href="links/main2.css"/>
8− <script src="scripts/wiki2.js"></script>
7+ <link rel="stylesheet" type="text/css" href="links/main.css"/>
8+ <script src="scripts/wiki.js"></script>
99 <script src="scripts/sites.js"></script>
1010 <script src="scripts/indental.js"></script>
1111 <title>Wiki</title>
wiki2.htmldeleted−20
@@ -1,20 +0,0 @@
1−<!DOCTYPE html>
2−<html lang="en">
3−<head>
4− <meta charset="utf-8">
5− <meta name="viewport" content="width=device-width, initial-scale=1.0">
6− <link rel="stylesheet" type="text/css" href="links/fonts.css"/>
7− <link rel="stylesheet" type="text/css" href="links/main.css"/>
8− <script src="scripts/wiki.js"></script>
9− <script src="scripts/sites.js"></script>
10− <script src="scripts/indental.js"></script>
11− <title>Wiki</title>
12−</head>
13−<body>
14− <script>
15− const wiki = new Wiki(sites);
16− wiki.install(document.body);
17− wiki.start();
18− </script>
19−</body>
20−</html>