@rathnasgala/theme 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/.gala/managed-files.json +15 -14
- package/payload/package.json +1 -1
- package/payload/src/_includes/components/ui.njk +10 -1
- package/payload/src/_includes/layouts/base.njk +6 -3
- package/payload/src/assets/interactions.js +39 -14
- package/payload/src/cname.11ty.js +53 -0
package/package.json
CHANGED
|
@@ -2,49 +2,50 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"themePackage": {
|
|
4
4
|
"name": "@rathnasgala/theme",
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.14",
|
|
6
6
|
"availableDesignThemes": [
|
|
7
7
|
"editorial"
|
|
8
8
|
],
|
|
9
9
|
"securityAdvisories": []
|
|
10
10
|
},
|
|
11
11
|
"files": {
|
|
12
|
-
".gitignore": "b5fa24e10155097a0d372926fd2e59e6072e7cc2cb6399bbfb4beb8b33ea315b",
|
|
13
12
|
".gala/publish.yml.template": "73080241d89bd09964b797a8bcc8e18471412e11bc873efad76305b60f497d08",
|
|
13
|
+
".gitignore": "b5fa24e10155097a0d372926fd2e59e6072e7cc2cb6399bbfb4beb8b33ea315b",
|
|
14
14
|
"eleventy.config.js": "efe587447e3dc374a220c7fa037fdf2fffc02d09ba43a4d2b96d6c6aae0e3325",
|
|
15
|
-
"package.json": "cccea6fc4edf4b4b653bd5cfc0901ab20dd92ac8975408fb01ae3670005da641",
|
|
16
|
-
"package-lock.json": "c97a6a2f794aef083a39a8d2628eccc4a3c484e1c6225899b77ec1fb7c466d9e",
|
|
17
15
|
"lib/build-manifest.js": "88949f0112d683ca809bb67ca969e15634792423559a67bc79a534cd807e5535",
|
|
18
|
-
"lib/site-config.js": "ab7cc170dc30c74ea5ef08b8ff6a82f9820998ae4190a06d64375dfd7d515864",
|
|
19
|
-
"lib/performance-budget.js": "124c43494c092a956accec46d1463ea063ed73363d0db01f24aaea987459d683",
|
|
20
16
|
"lib/engagement-snapshot.js": "298c11b1ab135a3a98a4e31b6320ab60dfd7fda6a9d9053df37d86282a5a6687",
|
|
17
|
+
"lib/performance-budget.js": "124c43494c092a956accec46d1463ea063ed73363d0db01f24aaea987459d683",
|
|
18
|
+
"lib/provider-fixtures/embeds.v1.json": "5f26909fb433135321ddf7fdd14e45aeb702805c88f5676941166c5735143ee2",
|
|
19
|
+
"lib/provider-fixtures/share-intents.v1.json": "66a8eedfcff711253ee45ceb94b53f7d5a6be3ddbbb3d1f0d4e31a114326cc0a",
|
|
21
20
|
"lib/publication-state.js": "1b59c29a18bbb1193bddea898dac3a4fb832c7bc4751263be086f3d64392dea0",
|
|
22
21
|
"lib/render-markdown.js": "40e6d6743b76de6c16d138475f188a4263967530c370d8b26a363f4df58c2caf",
|
|
23
22
|
"lib/seo.js": "107de8804931945b8e73894877fc394d6b535a9d0d969a4ba5b68f2e136e0a17",
|
|
24
23
|
"lib/share-targets.js": "458aff86fab2b62a364442cd8c612565c6e0b53eef2f20cb6237cc562b1e0731",
|
|
25
|
-
"lib/
|
|
26
|
-
"
|
|
24
|
+
"lib/site-config.js": "ab7cc170dc30c74ea5ef08b8ff6a82f9820998ae4190a06d64375dfd7d515864",
|
|
25
|
+
"package-lock.json": "c97a6a2f794aef083a39a8d2628eccc4a3c484e1c6225899b77ec1fb7c466d9e",
|
|
26
|
+
"package.json": "4c60bea06f39aec755ac68caf8d8841c1d59d0f6121fad7f4396231ce14712dc",
|
|
27
27
|
"src/404.njk": "be0d44370ac5402156aaf3d32ea581057bc61ec94c1a5f92bb809733af7a8a20",
|
|
28
|
-
"src/_includes/layouts/base.njk": "1bd300b68db1786b593ae5ef4325d68f21a5c79a78ac1cb3aba09fdba57bec9d",
|
|
29
|
-
"src/_includes/layouts/post.njk": "1accd2832064ad19ee7bf18daf5fa1e60569f32c9b7a547934a6361f747d7eb7",
|
|
30
|
-
"src/_includes/components/ui.njk": "de062ca818759edb53dc5e94ab839ac9453fda1fe458c61c04d9d89ef880c6af",
|
|
31
28
|
"src/_data/buildManifest.js": "628163305984e0d3537e27b0d4050f5ba5ead12a834878266d2ce8004ffe1b1e",
|
|
32
29
|
"src/_data/engagementSnapshot.js": "9217dacebfaf008f7a0ad67ff4e8d1fa8fba609a9dc7e3430c78c5b32024da0e",
|
|
33
30
|
"src/_data/feedLinks.js": "06c93352ebd888acb431a1c9a8be6ecff757895468e9f2d336761038751c2d5e",
|
|
34
31
|
"src/_data/languages.js": "1358748f7fa2f74406d3295a030827d6229a53e94da72cf712e719d7a356aeac",
|
|
35
32
|
"src/_data/site.js": "d9c001f4cc12a34027dd92303530b11b5402d47613459bb997e22c4bcbea326d",
|
|
36
|
-
"src/
|
|
37
|
-
"src/
|
|
33
|
+
"src/_includes/components/ui.njk": "b95eca21eb78182989c114f8d03342769553470672e7402e1330e9070c293ff5",
|
|
34
|
+
"src/_includes/layouts/base.njk": "d132b0a920e3dd9b60543394da4498b4d25b3821bdaaea0b3a5da55e9200b663",
|
|
35
|
+
"src/_includes/layouts/post.njk": "1accd2832064ad19ee7bf18daf5fa1e60569f32c9b7a547934a6361f747d7eb7",
|
|
38
36
|
"src/assets/embed-codepen.svg": "e9def697f38c466fb2b6652535c4c814e8cbbbefc6e052a69f335aeb27e8356b",
|
|
39
37
|
"src/assets/embed-gist.svg": "fcd9bc2bf29a5c118492b853c0a01390b7539c38ddb985da3c2a6e2f246a39f7",
|
|
40
38
|
"src/assets/embed-x.svg": "0ae74edc6790ec7e933067fe5392bce756e93fa7ad71caacf1c1ca99fa4ec9b6",
|
|
41
39
|
"src/assets/embed-youtube.svg": "10d192f2b14b67664fea88c8cf246321d20190def51d59fad5762e552219b067",
|
|
40
|
+
"src/assets/interactions.js": "fafa38854663f840fb4eb206d3ca06a836abf36bedb035a4e8ac211805709f09",
|
|
42
41
|
"src/assets/preferences.js": "789127bee013ed6a1bbf8cefd7b9109291c16220e7a6e09314e3c93c54731d1d",
|
|
43
42
|
"src/assets/search.js": "df425f0239277792ad39f2138bc89cb66cc4ecda5ed59042d46abc2f05372088",
|
|
43
|
+
"src/assets/theme-mode.js": "3797c84dbaa090b5b21427a31928b5dd97f13d04d99833f5e1e74c6b50e01dcc",
|
|
44
44
|
"src/assets/theme.css": "2c835fb79531d7b4a71bc2d41a6deb6e6b3689bf8603d903a3ba93add66c0d60",
|
|
45
|
+
"src/cname.11ty.js": "206fc224df91c569e18312158e7f69803061f2952513f501ada54bd06c4f8006",
|
|
45
46
|
"src/contact.njk": "f4d74d038781e15af0acef571901c91e7753a2e21b6bef617429585698839a34",
|
|
46
|
-
"src/index.njk": "5c313f0fcdad3ddbfb79376bc9671b3f37539ef70c14bdbbd26d6e2e6de250e8",
|
|
47
47
|
"src/feed.11ty.js": "009bd2384e08e02a9405683bab1653bab3aeaec16accb0fd01ba69b24c777da9",
|
|
48
|
+
"src/index.njk": "5c313f0fcdad3ddbfb79376bc9671b3f37539ef70c14bdbbd26d6e2e6de250e8",
|
|
48
49
|
"src/languages.11ty.js": "399559199c65570d7d5efd88e20254838e316f81c06d7b28ec34990e963db915",
|
|
49
50
|
"src/posts.11ty.js": "89c0e4742a67cd03f9fd13c8c8d4ca56375d97628b3cb439af7f9c92c240104a",
|
|
50
51
|
"src/redirects.11ty.js": "3c163246a59f5364861db6a6f05ae88afc938a5379d86cf42776d8d49b0031f3",
|
package/payload/package.json
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"scripts": {
|
|
7
7
|
"build": "eleventy",
|
|
8
8
|
"test": "node --test",
|
|
9
|
-
"lint": "node --check eleventy.config.js && node --check lib/build-manifest.js && node --check lib/engagement-snapshot.js && node --check lib/performance-budget.js && node --check lib/publication-state.js && node --check lib/render-markdown.js && node --check lib/seo.js && node --check lib/share-targets.js && node --check lib/site-config.js && node --check scripts/push.js && node --check src/_data/buildManifest.js && node --check src/_data/engagementSnapshot.js && node --check src/_data/feedLinks.js && node --check src/_data/languages.js && node --check src/_data/site.js && node --check src/assets/interactions.js && node --check src/assets/preferences.js && node --check src/assets/search.js && node --check src/assets/theme-mode.js && node --check src/feed.11ty.js && node --check src/languages.11ty.js && node --check src/posts.11ty.js && node --check src/redirects.11ty.js && node --check src/search-index.11ty.js && node --check src/sitemap.11ty.js && node --check test/build-manifest.test.js && node --check test/component-contract.test.js && node --check test/config.test.js && node --check test/eleventy-manifest-build.test.js && node --check test/engagement-client.test.js && node --check test/engagement-snapshot.test.js && node --check test/feed.test.js && node --check test/fixtures/xss-payloads.js && node --check test/managed-files.test.js && node --check test/performance-budget.test.js && node --check test/preferences.test.js && node --check test/publication-state.test.js && node --check test/render-markdown.test.js && node --check test/search.test.js && node --check test/seo.test.js && node --check test/share-targets.test.js && node --check test/supporting-surfaces.test.js && node --check test/theme-contract.test.js && node --check test/theme-contrast.test.js && node --check test/theme-mode.test.js && node --check test/theme-release-workflow.test.js",
|
|
9
|
+
"lint": "node --check eleventy.config.js && node --check lib/build-manifest.js && node --check lib/engagement-snapshot.js && node --check lib/performance-budget.js && node --check lib/publication-state.js && node --check lib/render-markdown.js && node --check lib/seo.js && node --check lib/share-targets.js && node --check lib/site-config.js && node --check scripts/push.js && node --check src/_data/buildManifest.js && node --check src/_data/engagementSnapshot.js && node --check src/_data/feedLinks.js && node --check src/_data/languages.js && node --check src/_data/site.js && node --check src/assets/interactions.js && node --check src/assets/preferences.js && node --check src/assets/search.js && node --check src/assets/theme-mode.js && node --check src/cname.11ty.js && node --check src/feed.11ty.js && node --check src/languages.11ty.js && node --check src/posts.11ty.js && node --check src/redirects.11ty.js && node --check src/search-index.11ty.js && node --check src/sitemap.11ty.js && node --check test/build-manifest.test.js && node --check test/cname.test.js && node --check test/component-contract.test.js && node --check test/config.test.js && node --check test/eleventy-manifest-build.test.js && node --check test/engagement-client.test.js && node --check test/engagement-snapshot.test.js && node --check test/feed.test.js && node --check test/fixtures/xss-payloads.js && node --check test/managed-files.test.js && node --check test/performance-budget.test.js && node --check test/preferences.test.js && node --check test/publication-state.test.js && node --check test/render-markdown.test.js && node --check test/search.test.js && node --check test/seo.test.js && node --check test/share-targets.test.js && node --check test/supporting-surfaces.test.js && node --check test/theme-contract.test.js && node --check test/theme-contrast.test.js && node --check test/theme-mode.test.js && node --check test/theme-release-workflow.test.js",
|
|
10
10
|
"push": "node scripts/push.js"
|
|
11
11
|
},
|
|
12
12
|
"engines": {
|
|
@@ -21,7 +21,16 @@
|
|
|
21
21
|
at the moment of intent, and the intent is replayed once they are back. #}
|
|
22
22
|
<section class="gala-engagement-actions" aria-label="Reader actions" data-engagement-actions>
|
|
23
23
|
<div class="gala-reaction-actions" role="group" aria-label="React to this article">
|
|
24
|
-
{
|
|
24
|
+
{# The six the platform actually stores (io.gala.api.engagement.ReactionType). Offering
|
|
25
|
+
any other name renders a button that can only ever fail on the way to the API. #}
|
|
26
|
+
{% for reaction in [
|
|
27
|
+
{ value: 'like', label: 'Like' },
|
|
28
|
+
{ value: 'insightful', label: 'Insightful' },
|
|
29
|
+
{ value: 'celebrate', label: 'Celebrate' },
|
|
30
|
+
{ value: 'funny', label: 'Funny' },
|
|
31
|
+
{ value: 'mind-blown', label: 'Mind blown' },
|
|
32
|
+
{ value: 'thank-you', label: 'Thank you' }
|
|
33
|
+
] %}<button type="button" data-reaction="{{ reaction.value }}" aria-pressed="false">{{ reaction.label }}</button>{% endfor %}
|
|
25
34
|
</div>
|
|
26
35
|
<button type="button" data-follow-article aria-pressed="false">Follow article</button>
|
|
27
36
|
<form data-comment-create>
|
|
@@ -56,11 +56,14 @@
|
|
|
56
56
|
<main id="main-content">{{ content | safe }}</main>
|
|
57
57
|
<footer class="gala-page-footer">
|
|
58
58
|
<p>© {{ site.site.name }}</p>
|
|
59
|
-
{# Which footer the click came from, which language it
|
|
60
|
-
|
|
59
|
+
{# Which repository sent the traffic, which footer the click came from, which language it
|
|
60
|
+
was read in, and which author owns it. Sites registered before these managed values
|
|
61
|
+
existed fall back rather than emitting the literal placeholder. #}
|
|
61
62
|
{% set galaLinkPlacement = 'article-footer' if post else 'site-footer' %}
|
|
62
63
|
{% set galaLinkLanguage = post.language or site.site.defaultLanguage %}
|
|
63
|
-
{%
|
|
64
|
+
{% set galaLinkSource = site.site.repository if site.site.repository and site.site.repository != 'unavailable' else 'gala-site' %}
|
|
65
|
+
{% set galaLinkOwner = site.site.ownerId if site.site.ownerId and site.site.ownerId != 'unavailable' else site.site.id %}
|
|
66
|
+
{% if attributionTier != 'PAID' %}<p><a href="https://gala67.com/?utm_source={{ galaLinkSource | urlencode }}&utm_medium=referral&utm_campaign=built-with-gala&utm_content={{ galaLinkPlacement | urlencode }}&utm_term={{ galaLinkLanguage | urlencode }}&utm_id={{ galaLinkOwner | urlencode }}" rel="external">Built with Gala</a></p>{% endif %}
|
|
64
67
|
</footer>
|
|
65
68
|
<dialog id="gala-settings-dialog" class="gala-dialog" aria-labelledby="gala-settings-title">
|
|
66
69
|
<form method="dialog" class="gala-dialog__close"><button type="submit" aria-label="Close settings">Close</button></form>
|
|
@@ -39,7 +39,10 @@ document.addEventListener('click', async (event) => {
|
|
|
39
39
|
if (reaction) {
|
|
40
40
|
const region = reaction.closest('[data-engagement-url]');
|
|
41
41
|
if (!region) return;
|
|
42
|
-
if (!sessionUser)
|
|
42
|
+
if (!sessionUser) {
|
|
43
|
+
return requestSession({ kind: 'reaction', region,
|
|
44
|
+
selector: `[data-reaction="${reaction.dataset.reaction}"]` });
|
|
45
|
+
}
|
|
43
46
|
const active = reaction.getAttribute('aria-pressed') !== 'true';
|
|
44
47
|
const saved = await mutateEngagement(region, active ? 'reaction.add' : 'reaction.remove', {
|
|
45
48
|
articleId: region.dataset.articleId,
|
|
@@ -54,7 +57,9 @@ document.addEventListener('click', async (event) => {
|
|
|
54
57
|
if (follow) {
|
|
55
58
|
const region = follow.closest('[data-engagement-url]');
|
|
56
59
|
if (!region) return;
|
|
57
|
-
if (!sessionUser)
|
|
60
|
+
if (!sessionUser) {
|
|
61
|
+
return requestSession({ kind: 'follow', region, selector: '[data-follow-article]' });
|
|
62
|
+
}
|
|
58
63
|
const active = follow.getAttribute('aria-pressed') !== 'true';
|
|
59
64
|
const saved = await mutateEngagement(region, active ? 'follow.add' : 'follow.remove', {
|
|
60
65
|
targetType: 'articles', targetId: region.dataset.articleId
|
|
@@ -358,7 +363,13 @@ function recordView(region) {
|
|
|
358
363
|
document.addEventListener('focusin', (event) => {
|
|
359
364
|
if (sessionUser || pendingIntent) return;
|
|
360
365
|
const field = event.target.closest('[data-comment-create] textarea, [data-comment-editor] textarea');
|
|
361
|
-
if (field)
|
|
366
|
+
if (!field) return;
|
|
367
|
+
const region = field.closest('[data-engagement-url]');
|
|
368
|
+
const form = field.closest('[data-comment-create], [data-comment-editor]');
|
|
369
|
+
if (!region || !form) return;
|
|
370
|
+
requestSession({ kind: 'comment', region,
|
|
371
|
+
selector: `${form.matches('[data-comment-create]') ? '[data-comment-create]' : '[data-comment-editor]'} textarea`,
|
|
372
|
+
field });
|
|
362
373
|
});
|
|
363
374
|
|
|
364
375
|
document.addEventListener('submit', async (event) => {
|
|
@@ -371,7 +382,9 @@ document.addEventListener('submit', async (event) => {
|
|
|
371
382
|
const body = form.elements.body?.value;
|
|
372
383
|
if (!region || typeof body !== 'string' || body.trim() === '') return;
|
|
373
384
|
if (!sessionUser) {
|
|
374
|
-
return requestSession({ kind: 'comment',
|
|
385
|
+
return requestSession({ kind: 'comment', region,
|
|
386
|
+
selector: `${create ? '[data-comment-create]' : '[data-comment-editor]'} textarea`,
|
|
387
|
+
field: form.querySelector('textarea') });
|
|
375
388
|
}
|
|
376
389
|
if (create) {
|
|
377
390
|
const saved = await mutateEngagement(region, 'comment.create', {
|
|
@@ -407,13 +420,14 @@ const pendingEngagementWrites = new Map();
|
|
|
407
420
|
let pendingIntent = null;
|
|
408
421
|
|
|
409
422
|
function requestSession(intent) {
|
|
410
|
-
const field = intent.
|
|
423
|
+
const field = intent.field;
|
|
411
424
|
pendingIntent = {
|
|
412
425
|
kind: intent.kind,
|
|
413
|
-
|
|
426
|
+
region: intent.region,
|
|
427
|
+
selector: intent.selector,
|
|
414
428
|
// Held here rather than left in the DOM, because signing in re-renders the region.
|
|
415
|
-
draft: field
|
|
416
|
-
caret: field
|
|
429
|
+
draft: field ? field.value : null,
|
|
430
|
+
caret: field ? field.selectionStart : null
|
|
417
431
|
};
|
|
418
432
|
// One window, not three. Asking used to open a modal, containing a frame, containing a
|
|
419
433
|
// button, that opened a popup. The popup is the only part that has to exist, because it is
|
|
@@ -424,7 +438,7 @@ function requestSession(intent) {
|
|
|
424
438
|
const source = new URL(frame.getAttribute('src'), window.location.href);
|
|
425
439
|
const signIn = new URL('/v1/widget/session/sign-in', source.origin);
|
|
426
440
|
signIn.searchParams.set('siteId', source.searchParams.get('siteId') ?? '');
|
|
427
|
-
if (field
|
|
441
|
+
if (field) field.blur();
|
|
428
442
|
if (!window.open(signIn, 'gala-sign-in', 'popup,width=520,height=680')) {
|
|
429
443
|
pendingIntent = null;
|
|
430
444
|
if (status) status.textContent = 'Allow pop-ups for this site to sign in, then try again.';
|
|
@@ -434,14 +448,19 @@ function requestSession(intent) {
|
|
|
434
448
|
/** Puts the reader back exactly where the sign-in interrupted them. */
|
|
435
449
|
function resumeIntent() {
|
|
436
450
|
const intent = pendingIntent;
|
|
437
|
-
pendingIntent = null;
|
|
438
451
|
if (!intent) return;
|
|
439
|
-
|
|
440
|
-
|
|
452
|
+
// The sign-in window is still closing at the moment the session arrives, so focus set now
|
|
453
|
+
// would be handed straight back to it. Wait until this page actually holds focus.
|
|
454
|
+
if (!document.hasFocus()) return;
|
|
455
|
+
// Re-found rather than remembered: signing in re-renders the engagement region, so a node
|
|
456
|
+
// captured before the interruption may no longer be the one on the page.
|
|
457
|
+
const element = intent.region?.querySelector(intent.selector);
|
|
458
|
+
if (!element) return;
|
|
459
|
+
pendingIntent = null;
|
|
441
460
|
if (intent.kind === 'comment') {
|
|
442
|
-
if (
|
|
461
|
+
if (intent.draft != null && element.value === '') element.value = intent.draft;
|
|
443
462
|
element.focus();
|
|
444
|
-
if (intent.caret != null &&
|
|
463
|
+
if (intent.caret != null && typeof element.setSelectionRange === 'function') {
|
|
445
464
|
element.setSelectionRange(intent.caret, intent.caret);
|
|
446
465
|
}
|
|
447
466
|
return;
|
|
@@ -451,6 +470,12 @@ function resumeIntent() {
|
|
|
451
470
|
element.click();
|
|
452
471
|
}
|
|
453
472
|
|
|
473
|
+
// Signing in happens in another window, so the moment this one is focused again is the moment
|
|
474
|
+
// the reader is back and the interrupted action can be finished.
|
|
475
|
+
window.addEventListener('focus', () => {
|
|
476
|
+
if (sessionUser && pendingIntent) resumeIntent();
|
|
477
|
+
});
|
|
478
|
+
|
|
454
479
|
document.querySelectorAll('[data-engagement-url]').forEach((region) => {
|
|
455
480
|
refreshEngagement(region);
|
|
456
481
|
recordView(region);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Emits the CNAME file GitHub Pages needs to serve a custom domain.
|
|
3
|
+
*
|
|
4
|
+
* The published branch is force-pushed on every run, so anything not produced by the build is
|
|
5
|
+
* gone the next time someone writes a post. Deriving it from the site configuration means the
|
|
6
|
+
* custom domain is restated on every publish and cannot be lost, and there is exactly one place
|
|
7
|
+
* that decides what the domain is.
|
|
8
|
+
*/
|
|
9
|
+
const PROVIDER_HOST = /\.github\.io$/;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The host this repository may claim as its own, or null.
|
|
13
|
+
*
|
|
14
|
+
* A site served under a path is served that way because GitHub gives it the domain held by the
|
|
15
|
+
* owner's main site — https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/about-custom-domains-and-github-pages
|
|
16
|
+
* puts a project site at `www.octocat.com/octo-project`. GitHub reads this file from the
|
|
17
|
+
* published branch and treats it as *this* repository's own domain, which overrides that
|
|
18
|
+
* inheritance: the blog would move to the domain root and take the address away from the site
|
|
19
|
+
* that owns it. So a path-prefixed site deliberately claims nothing.
|
|
20
|
+
*/
|
|
21
|
+
export function customDomainHost(canonicalBaseUrl, pathPrefix = '/') {
|
|
22
|
+
if (pathPrefix !== '/') return null;
|
|
23
|
+
if (typeof canonicalBaseUrl !== 'string' || canonicalBaseUrl === '') return null;
|
|
24
|
+
let host;
|
|
25
|
+
try {
|
|
26
|
+
host = new URL(canonicalBaseUrl).host;
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
// A provider-default site is served from the owner's github.io origin and must not claim a
|
|
31
|
+
// custom domain, or GitHub would reject a domain it cannot verify.
|
|
32
|
+
return PROVIDER_HOST.test(host) ? null : host;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function claimed(site) {
|
|
36
|
+
return customDomainHost(site?.hosting?.canonicalBaseUrl, site?.hosting?.pathPrefix ?? '/');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export default class CustomDomain {
|
|
40
|
+
data() {
|
|
41
|
+
return {
|
|
42
|
+
permalink: ({ site }) => claimed(site) ? '/CNAME' : false,
|
|
43
|
+
// GitHub Pages requires this exact extensionless name, so Eleventy's guard against
|
|
44
|
+
// extensionless output does not apply here.
|
|
45
|
+
eleventyAllowMissingExtension: true,
|
|
46
|
+
eleventyExcludeFromCollections: true
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
render({ site }) {
|
|
51
|
+
return `${claimed(site)}\n`;
|
|
52
|
+
}
|
|
53
|
+
}
|