tangled
alpha
login
or
join now
chriskrycho.com
/
v5.chriskrycho.com
2
fork
atom
The fifth version of chriskrycho.com, built in Eleventy.
2
fork
atom
overview
issues
pulls
pipelines
Update with a year's worth of changes
chriskrycho.com
2 years ago
2f8dff39
78be6c13
+53
-56
14 changed files
expand all
collapse all
unified
split
eleventy
config.ts
feed.ts
package-lock.json
rollup.config.js
scripts
ColorScheme.svelte
Preferences.svelte
ReadingMode.svelte
main.js
tsconfig.json
site
_includes
base.njk
styles
_components.scss
components
_preferences.scss
tsconfig.base.json
types
markdown-it-sup.d.ts
+6
-12
eleventy/config.ts
···
26
26
27
27
import './feed'; // for extension of types -- TODO: move those types elsewhere!
28
28
29
29
-
type Not = <A extends unknown[]>(
30
30
-
pred: (...args: A) => boolean,
31
31
-
) => (...args: A) => boolean;
32
32
-
const not: Not =
33
33
-
(fn) =>
34
34
-
(...args) =>
35
35
-
!fn(...args);
29
29
+
type Not = <A extends unknown[]>(fn: (...args: A) => boolean) => (...args: A) => boolean;
30
30
+
// prettier-ignore
31
31
+
const not: Not = (fn) => (...args) => !fn(...args);
36
32
37
37
-
const filter =
38
38
-
<T>(pred: (t: T) => boolean) =>
39
39
-
(values: T[]) =>
40
40
-
values.filter(pred);
33
33
+
type Filter = <T>(pred: (t: T) => boolean) => (values: T[]) => T[];
34
34
+
const filter: Filter = (pred) => (values) => values.filter(pred);
41
35
42
36
const BUILD_TIME = DateTime.fromJSDate(new Date(), TZ).toSeconds();
43
37
···
235
229
};
236
230
}
237
231
238
238
-
// Needs to be this way so that the import resolves as expected in `.eleventy.js`.
232
232
+
// Needs to be this way so that the import resolves as expected in `.eleventy`.
239
233
module.exports = config;
+10
-7
eleventy/feed.ts
···
1
1
-
import stripTags from 'striptags';
1
1
+
import striptags from 'striptags';
2
2
+
import { DateTime } from 'luxon';
3
3
+
import { Result } from 'true-myth';
2
4
3
5
import { Dict, EleventyClass, Item } from '../types/eleventy';
4
6
import JsonFeed, { FeedItem } from '../types/json-feed';
···
9
11
import { toRootCollection } from './collection';
10
12
import markdown from './markdown';
11
13
import localeDate from './locale-date';
12
12
-
import { DateTime } from 'luxon';
13
13
-
import { Result } from 'true-myth';
14
14
15
15
type BuildInfo = typeof import('../site/_data/build');
16
16
type SiteConfig = typeof import('../site/_data/config');
···
177
177
${item.data.updates
178
178
.map(
179
179
({ at, changes }) =>
180
180
-
`<li><b>${localeDate(at, 'yyyy/MM/dd HH:mm')}:</b> ${markdown.renderInline(changes)}</li>`,
180
180
+
`<li><b>${localeDate(
181
181
+
at,
182
182
+
'yyyy/MM/dd HH:mm',
183
183
+
)}:</b> ${markdown.renderInline(changes)}</li>`,
181
184
)
182
185
.join('\n')}
183
186
</ul>`
···
226
229
) ?? false;
227
230
const photoTitleAllowed = !(isPhoto && photoItemTitles === 'off');
228
231
const showTitle = sectionMarker && title && photoTitleAllowed;
229
229
-
return showTitle ? `[${sectionMarker}] ${stripTags(title)}` : undefined;
232
232
+
return showTitle ? `[${sectionMarker}] ${striptags(title)}` : undefined;
230
233
}
231
234
232
235
function summaryFor(item: Item): string {
233
233
-
return item.data?.summary ?? item.data?.subtitle ?? stripTags(item.templateContent);
236
236
+
return item.data?.summary ?? item.data?.subtitle ?? striptags(item.templateContent);
234
237
}
235
238
236
239
/**
···
344
347
permalink: (/* _: EleventyData */): string => {
345
348
return (
346
349
this.permalink ??
347
347
-
(this.collection ? `/${this.collection}/feed.json` : '/feed.json')
350
350
+
(this.collection ? `/${this.collection}/feedon` : '/feedon')
348
351
);
349
352
},
350
353
};
+4
-1
package-lock.json
···
9878
9878
},
9879
9879
"node_modules/true-myth": {
9880
9880
"version": "4.1.1",
9881
9881
+
"resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz",
9882
9882
+
"integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==",
9881
9883
"dev": true,
9882
9882
-
"license": "MIT",
9883
9884
"engines": {
9884
9885
"node": "10.* || >= 12.*"
9885
9886
}
···
17729
17730
},
17730
17731
"true-myth": {
17731
17732
"version": "4.1.1",
17733
17733
+
"resolved": "https://registry.npmjs.org/true-myth/-/true-myth-4.1.1.tgz",
17734
17734
+
"integrity": "sha512-rqy30BSpxPznbbTcAcci90oZ1YR4DqvKcNXNerG5gQBU2v4jk0cygheiul5J6ExIMrgDVuanv/MkGfqZbKrNNg==",
17732
17735
"dev": true
17733
17736
},
17734
17737
"ts-node": {
+1
-4
rollup.config.js
···
12
12
sourcemap: true,
13
13
format: 'iife',
14
14
name: 'app',
15
15
-
file: './site/assets/js/main.js',
15
15
+
file: './site/_assets/js/main.js',
16
16
},
17
17
plugins: [
18
18
// teach rollup how to handle typescript imports
···
23
23
svelte({
24
24
preprocess: autoPreprocess({
25
25
sourceMap: true,
26
26
-
defaults: {
27
27
-
script: 'typescript',
28
28
-
},
29
26
typescript: '',
30
27
}),
31
28
compilerOptions: {
+4
-7
scripts/ColorScheme.svelte
···
1
1
<script lang="ts">
2
2
-
import { stringIsTheme, Theme } from './preferences';
2
2
+
import { isTheme, Theme } from './preferences';
3
3
import { assert } from './utils';
4
4
5
5
const themes = [Theme.System, Theme.Light, Theme.Dark] as const;
···
10
10
dark: 'dark',
11
11
};
12
12
13
13
-
let selectTheme = (event: Event) => {
14
14
-
assert(event.target instanceof HTMLInputElement, 'badly configured theme chooser');
15
15
-
assert(stringIsTheme(event.target.value), 'badly configured theme component');
16
16
-
17
17
-
onSelectTheme(event.target.value);
13
13
+
let selectTheme: svelte.JSX.FormEventHandler<HTMLInputElement> = (event) => {
14
14
+
assert(isTheme(event.currentTarget.value), 'badly configured theme component');
15
15
+
onSelectTheme(event.currentTarget.value);
18
16
};
19
17
20
18
export let selectedTheme: Theme = Theme.System;
21
19
export let onSelectTheme: (newTheme: Theme) => void;
22
22
-
23
20
</script>
24
21
25
22
<fieldset>
+1
-2
scripts/Preferences.svelte
···
1
1
-
<script>
1
1
+
<script lang="ts">
2
2
import ColorScheme from './ColorScheme.svelte';
3
3
import Adjust from './Icons/Adjust.svelte';
4
4
import Close from './Icons/Close.svelte';
···
27
27
persistReadingMode(newValue);
28
28
readingMode = newValue;
29
29
};
30
30
-
31
30
</script>
32
31
33
32
{#if !showPreferences}
+5
-10
scripts/ReadingMode.svelte
···
1
1
-
<script lang="typescript">
2
2
-
import { assert } from './utils'
1
1
+
<script lang="ts">
2
2
+
import { assert } from './utils';
3
3
4
4
-
function setReadingMode(event: Event) {
5
5
-
assert(event.target instanceof HTMLInputElement, 'badly configured reading mode')
6
6
-
onSetReadingMode(event.target.checked)
7
7
-
}
8
8
-
9
9
-
export let onSetReadingMode: (newValue: boolean) => void
10
10
-
export let inReadingMode: boolean
4
4
+
export let onSetReadingMode: (newValue: boolean) => void;
5
5
+
export let inReadingMode: boolean;
11
6
</script>
12
7
13
8
<fieldset>
···
17
12
name="reading-mode"
18
13
id="reading-mode"
19
14
checked={inReadingMode}
20
20
-
on:change={setReadingMode}
15
15
+
on:change={(event) => onSetReadingMode(event.currentTarget.checked)}
21
16
/>
22
17
</fieldset>
+4
-4
scripts/main.js
···
1
1
-
import Preferences from './Preferences.svelte'
2
2
-
import { selectorFor } from './utils'
1
1
+
import Preferences from './Preferences.svelte';
2
2
+
import { selectorFor } from './utils.js';
3
3
4
4
const preferences = new Preferences({
5
5
target: document.querySelector(selectorFor('preferences')),
6
6
-
})
6
6
+
});
7
7
8
8
-
export default preferences
8
8
+
export default preferences;
+1
-1
scripts/tsconfig.json
···
5
5
"removeComments": true,
6
6
"lib": ["dom", "es2019"],
7
7
"noEmit": false,
8
8
-
"inlineSources": true,
8
8
+
"inlineSources": false,
9
9
"sourceMap": true,
10
10
"baseUrl": "scripts"
11
11
},
+2
-2
site/_includes/base.njk
···
56
56
57
57
<link rel='preload' as='script' type='application/javascript' href='/assets/js/main.js'>
58
58
59
59
-
<meta name="author" content="Chris Krycho" />
59
59
+
<meta name="author" content="Chris Krycho"/>
60
60
61
61
{% block meta %}
62
62
{{ social.meta(page, config) }}
···
96
96
<div data-sympolymathesy='preferences' class='preferences no-js-hidden'></div>
97
97
<script src='/assets/js/main.js'></script>
98
98
</body>
99
99
-
</html>
99
99
+
</html>
+2
site/_includes/styles/_components.scss
···
9
9
@import 'components/note';
10
10
@import 'components/post-meta';
11
11
@import 'components/site-nav';
12
12
+
13
13
+
@import 'components/preferences';
+10
-4
site/_includes/styles/components/_preferences.scss
···
1
1
.preferences {
2
2
font: var(--sans);
3
3
-
position: absolute;
3
3
+
position: fixed;
4
4
top: 1em;
5
5
right: 1em;
6
6
+
7
7
+
background: var(--bg);
8
8
+
color: var(--fg);
6
9
}
7
10
8
11
.preferences-button {
9
9
-
position: absolute;
10
10
-
top: 0;
11
11
-
right: 0;
12
12
+
position: fixed;
13
13
+
top: 1em;
14
14
+
right: 1em;
15
15
+
background: var(--bg);
16
16
+
color: var(--fg);
17
17
+
border: none;
12
18
}
+2
tsconfig.base.json
···
5
5
"lib": ["es2019"] /* Specify library files to be included in the compilation. */,
6
6
"checkJs": true /* Report errors in .js files. */,
7
7
"allowJs": true,
8
8
+
"moduleResolution": "node",
9
9
+
"module": "node12",
8
10
9
11
/* Strict Type-Checking Options */
10
12
"strict": true /* Enable all strict type-checking options. */,
+1
-2
types/markdown-it-sup.d.ts
···
6
6
7
7
import MarkdownIt = require('markdown-it');
8
8
9
9
-
declare function sup(md: MarkdownIt): void;
10
10
-
export = sup;
9
9
+
export default function sup(md: MarkdownIt): void;