on 3d3eec8 help sign in
webring/scripts/wiki.js
111 lines 3.5 kB history raw
1'use strict'
3function Wiki (sites) {
4 const feeds = {}
5 this.sites = sites
6 this._el = document.createElement('div')
7 this._el.id = 'wiki'
8 this._sidebar = document.createElement('div')
9 this._sidebar.id = 'sidebar'
10 this._categories = document.createElement('ul')
11 this._categories.id = 'categories'
12 this._entry = document.createElement('div')
13 this._entry.id = 'entry'
15 this.loc = ''
16 this.index = {}
17 this.categories = {}
19 this.install = (host) => {
20 console.log('Wiki', 'Installing..')
21 this.fetch()
22 this._el.appendChild(this._entry)
23 this._sidebar.appendChild(this._categories)
24 this._el.appendChild(this._sidebar)
25 host.appendChild(this._el)
26 }
28 this.start = () => {
29 console.log('Wiki', 'Starting..')
30 // this.el.innerHTML = 'hello.'
31 }
33 this.refresh = () => {
34 console.log(Object.keys(this.index).length + ' terms')
35 // Main
36 if (this.loc) {
37 if (this.categories[this.index]) {
38 let html = `term: ${this.loc}`
39 this._entry.innerHTML = html
40 } else if (this.categories[this.loc]) {
41 let html = ''
42 for (const id in this.categories[this.loc]) {
43 const name = this.categories[this.loc][id].name
44 html += `${this.templateTerm(name, this.index[name])}<br />`
45 }
46 this._entry.innerHTML = html
47 } else {
48 let html = `Unknown: ${this.loc}`
49 this._entry.innerHTML = html
50 }
51 } else {
52 this._entry.innerHTML = 'Click a /topic to get started.'
53 }
54 // Sidebar
55 this._categories.innerHTML = Object.keys(this.categories).reduce((acc, id) => { return `${acc}<li onclick='wiki.go("${id}")' class='${wiki.at(id) ? 'selected' : ''}'>${id.substr(0, 20)} <span class='right'>${this.categories[id].length}</span></li>` }, '')
56 }
58 this.go = (q) => {
59 this.loc = q
60 window.location.hash = q.toUrl()
61 this.refresh()
62 }
64 this.at = (q = '') => {
65 return this.loc.toUpperCase() === q.toUpperCase()
66 }
68 this.templateTerm = (name, entry) => {
69 return '<ul class="term"><li class="name"><b>' + name.toLowerCase() + '</b></li>' + entry.reduce((acc, item) => { return `${acc}<li>${item.value} <a class='author' href='${item.origin.url}'> — @${item.origin.author}</a></li>` }, '') + '</ul>'
70 }
72 this.fetch = () => {
73 console.log('Wiki', 'Fetching..')
74 for (const site of sites) {
75 if (!site.wiki || !site.author) { continue }
76 fetch(site.wiki, { cache: 'no-store' }).then(x => x.text()).then((content) => {
77 this.parse(site, content)
78 this.refresh(feeds)
79 }).catch((err) => {
80 console.warn(`${site.wiki}`, err)
81 })
82 }
83 }
85 this.add = (name, value, cat, origin) => {
86 if (!this.index[name]) {
87 this.index[name] = []
88 }
89 this.index[name].push({ name, value, cat, origin })
90 if (!this.categories[cat]) {
91 this.categories[cat] = []
92 }
93 this.categories[cat].push({ name, value, cat, origin })
94 }
96 this.parse = (site, content) => {
97 console.log('Wiki', 'Parsing ' + site.wiki)
98 const cats = indental(this.filter(content))
99 for (const cat in cats) {
100 const terms = cats[cat]
101 for (const name in terms) {
102 this.add(name, terms[name], cat, site)
103 }
104 }
105 }
107 this.filter = (lines) => {
108 return lines.split('\n').filter((line) => { return line.indexOf(' = `') < 0 && line.trim().length > 1 }).join('\n')
109 }
110 String.prototype.toUrl = function () { return this.toLowerCase().replace(/ /g, '+').replace(/[^0-9a-z\+\:\-\.\/\~]/gi, '').trim() }