« get me outta code hell

link.js « util « src - hsmusic-wiki - HSMusic - static wiki software cataloguing collaborative creation
about summary refs log tree commit diff
path: root/src/util/link.js
blob: 4e611df5b8d1a303d02286fab191f94be224b703 (plain)
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
// This file is essentially one level of a8straction a8ove urls.js (and the
// urlSpec it gets its paths from). It's a 8unch of utility functions which
// take certain types of wiki data o8jects (colloquially known as "things")
// and return actual <a href> HTML link tags.
//
// The functions we're cre8ting here (all factory-style) take a "to" argument,
// which is roughly a function which takes a urlSpec key and spits out a path
// to 8e stuck in an href or src or suchever. There are also a few other
// options availa8le in all the functions, making a common interface for
// gener8ting just a8out any link on the site.

import * as html from './html.js'
import { getColors } from './colors.js'

export function getLinkThemeString(color) {
    if (!color) return '';

    const { primary, dim } = getColors(color);
    return `--primary-color: ${primary}; --dim-color: ${dim}`;
}

const appendIndexHTMLRegex = /^(?!https?:\/\/).+\/$/;

const linkHelper = (hrefFn, {color = true, attr = null} = {}) =>
    (thing, {
        to,
        text = '',
        attributes = null,
        class: className = '',
        color: color2 = true,
        hash = ''
    }) => {
        let href = hrefFn(thing, {to});

        if (link.globalOptions.appendIndexHTML) {
            if (appendIndexHTMLRegex.test(href)) {
                href += 'index.html';
            }
        }

        if (hash) {
            href += (hash.startsWith('#') ? '' : '#') + hash;
        }

        return html.tag('a', {
            ...attr ? attr(thing) : {},
            ...attributes ? attributes : {},
            href,
            style: (
                typeof color2 === 'string' ? getLinkThemeString(color2) :
                color2 && color ? getLinkThemeString(thing.color) :
                ''),
            class: className
        }, text || thing.name)
    };

const linkDirectory = (key, {expose = null, attr = null, ...conf} = {}) =>
    linkHelper((thing, {to}) => to('localized.' + key, thing.directory), {
        attr: thing => ({
            ...attr ? attr(thing) : {},
            ...expose ? {[expose]: thing.directory} : {}
        }),
        ...conf
    });

const linkPathname = (key, conf) => linkHelper(({directory: pathname}, {to}) => to(key, pathname), conf);
const linkIndex = (key, conf) => linkHelper((_, {to}) => to('localized.' + key), conf);

const link = {
    globalOptions: {
        // This should usually only 8e used during development! It'll take any
        // href that ends with `/` and append `index.html` to the returned
        // value (for to.thing() functions). This is handy when developing
        // without a local server (i.e. using file:// protocol URLs in your
        // 8rowser), 8ut isn't guaranteed to 8e 100% 8ug-free.
        appendIndexHTML: false
    },

    album: linkDirectory('album'),
    albumCommentary: linkDirectory('albumCommentary'),
    artist: linkDirectory('artist', {color: false}),
    artistGallery: linkDirectory('artistGallery', {color: false}),
    commentaryIndex: linkIndex('commentaryIndex', {color: false}),
    flashIndex: linkIndex('flashIndex', {color: false}),
    flash: linkDirectory('flash'),
    groupInfo: linkDirectory('groupInfo'),
    groupGallery: linkDirectory('groupGallery'),
    home: linkIndex('home', {color: false}),
    listingIndex: linkIndex('listingIndex'),
    listing: linkDirectory('listing'),
    newsIndex: linkIndex('newsIndex', {color: false}),
    newsEntry: linkDirectory('newsEntry', {color: false}),
    staticPage: linkDirectory('staticPage', {color: false}),
    tag: linkDirectory('tag'),
    track: linkDirectory('track', {expose: 'data-track'}),

    media: linkPathname('media.path', {color: false}),
    root: linkPathname('shared.path', {color: false}),
    data: linkPathname('data.path', {color: false}),
    site: linkPathname('localized.path', {color: false})
};

export default link;