scavold 0.2.0-rc.10 → 0.2.0-rc.12
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/CHANGELOG.md +22 -1
- package/COMPONENTS.md +87 -5
- package/components/ScavoldCover.vue +2 -2
- package/composables/useCover.js +19 -2
- package/index.d.ts +3 -0
- package/lib/config.js +16 -2
- package/lib/containers.js +30 -3
- package/lib/sectionManifest.js +6 -0
- package/package.json +1 -1
- package/scripts/check-fixture.js +9 -0
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,25 @@ changes may occur in any release.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.2.0-rc.12] — 2026-10-03
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- `:::cover` takes `tone=light` or `tone=dark` for content on top that is meant to be
|
|
17
|
+
light or dark, depending on the picture. It only marks the cover with
|
|
18
|
+
`scavold-cover--light` or `scavold-cover--dark`; the colours are the theme's. The
|
|
19
|
+
editor offers it as a choice.
|
|
20
|
+
|
|
21
|
+
## [0.2.0-rc.11] — 2026-10-01
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- A container opening a page carries an empty `data-leading` attribute, and the page
|
|
26
|
+
data name it as `leadingContainer` — known before the content renders, so a layout
|
|
27
|
+
can arrange its own parts around a cover at the top of a page, e.g. move its
|
|
28
|
+
breadcrumb below it. Both are information only; nothing changes for a theme that
|
|
29
|
+
does not ask.
|
|
30
|
+
|
|
12
31
|
## [0.2.0-rc.10] — 2026-10-01
|
|
13
32
|
|
|
14
33
|
### Added
|
|
@@ -324,7 +343,9 @@ First published release. Version `0.1.0` existed in-tree only.
|
|
|
324
343
|
- Only images are processed out of `media_folder`; other file types (video, documents)
|
|
325
344
|
are never copied into the build output and have to live in the static folder.
|
|
326
345
|
|
|
327
|
-
[Unreleased]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.
|
|
346
|
+
[Unreleased]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.12...main
|
|
347
|
+
[0.2.0-rc.12]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.11...v0.2.0-rc.12
|
|
348
|
+
[0.2.0-rc.11]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.10...v0.2.0-rc.11
|
|
328
349
|
[0.2.0-rc.10]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.9...v0.2.0-rc.10
|
|
329
350
|
[0.2.0-rc.9]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.8...v0.2.0-rc.9
|
|
330
351
|
[0.2.0-rc.8]: https://gitlab.com/cratly/scavold/-/compare/v0.2.0-rc.7...v0.2.0-rc.8
|
package/COMPONENTS.md
CHANGED
|
@@ -451,12 +451,13 @@ the window, cropped to fit — a cover, or hero, at the top of a page. Written a
|
|
|
451
451
|
| `poster` | `media-file` | — | Only for a video: still image shown until it plays, and instead of playing for visitors who asked for reduced motion. |
|
|
452
452
|
| `focus` | `string` | `50% 50%` | Part of the picture kept visible when the window crops it, as a CSS `object-position` — `center top`, `30% 60%`. |
|
|
453
453
|
| `label` | `string` | — | Alternative text of an image, accessible label of a video. Left out, the picture is treated as decoration. |
|
|
454
|
+
| `tone` | `"light" \| "dark"` | — | Whether the content on top is meant to be light (over a dark picture) or dark (over a bright one). Only marks the cover with `scavold-cover--light` or `scavold-cover--dark`; what that looks like is the theme's. Left out, or with any other value, the cover carries neither class. |
|
|
454
455
|
|
|
455
456
|
#### Rendered markup
|
|
456
457
|
|
|
457
458
|
```html
|
|
458
|
-
<!-- image -->
|
|
459
|
-
<div class="scavold-cover" style="--scavold-cover-focus: center top">
|
|
459
|
+
<!-- image, tone=light -->
|
|
460
|
+
<div class="scavold-cover scavold-cover--light" style="--scavold-cover-focus: center top">
|
|
460
461
|
<picture class="scavold-cover__media">
|
|
461
462
|
<source type="image/webp" srcset="..." sizes="(min-aspect-ratio: 2400/1350) 100vw, 177.78vh" />
|
|
462
463
|
<source srcset="..." sizes="..." />
|
|
@@ -504,6 +505,80 @@ html { overflow-x: clip; }
|
|
|
504
505
|
The overlay is an empty grid cell over the picture; position its content, add a scrim
|
|
505
506
|
for legibility and restyle `.scavold-cover__toggle` as the design asks.
|
|
506
507
|
|
|
508
|
+
The `tone` an author picked is the theme's to honour. Scavold sets no colour for it;
|
|
509
|
+
a theme gives each tone the colours of its design, including headings and links its
|
|
510
|
+
prose styles colour on their own:
|
|
511
|
+
|
|
512
|
+
```css
|
|
513
|
+
.scavold-cover--light .scavold-cover__overlay { color: #fff; }
|
|
514
|
+
.scavold-cover--dark .scavold-cover__overlay { color: #000; }
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
#### A cover opening the page
|
|
518
|
+
|
|
519
|
+
Where the theme's own parts go around a cover is the theme's choice; Scavold places
|
|
520
|
+
none of them. It only tells, in two ways, that a page opens with a container:
|
|
521
|
+
|
|
522
|
+
- the container carries an empty `data-leading` attribute;
|
|
523
|
+
- the page data carry `leadingContainer`, the name of that container (`"cover"`), or
|
|
524
|
+
`null` when the page opens with anything else. A layout renders its own parts before
|
|
525
|
+
the page content, so this is known at build time, ahead of the content.
|
|
526
|
+
|
|
527
|
+
A theme that wants its breadcrumb below a cover opening the page, rather than above
|
|
528
|
+
it, combines both. The layout leaves out the breadcrumb on such a page:
|
|
529
|
+
|
|
530
|
+
```vue
|
|
531
|
+
<!-- Layout.vue -->
|
|
532
|
+
<script setup>
|
|
533
|
+
import { useData } from "vitepress";
|
|
534
|
+
const { page } = useData();
|
|
535
|
+
</script>
|
|
536
|
+
|
|
537
|
+
<template>
|
|
538
|
+
<ScavoldBreadcrumb v-if="page.leadingContainer !== 'cover'" />
|
|
539
|
+
<Content />
|
|
540
|
+
</template>
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
…and the cover is mapped to a component of the site's own that wraps the built-in one
|
|
544
|
+
and adds the breadcrumb after it when it is the leading one:
|
|
545
|
+
|
|
546
|
+
```yaml
|
|
547
|
+
# .cratly.config.yaml — the editor keeps offering the cover's own properties
|
|
548
|
+
containers:
|
|
549
|
+
cover:
|
|
550
|
+
component: SiteCover
|
|
551
|
+
```
|
|
552
|
+
|
|
553
|
+
```vue
|
|
554
|
+
<!-- .vitepress/theme/components/SiteCover.vue -->
|
|
555
|
+
<script setup>
|
|
556
|
+
import ScavoldCover from "scavold/components/ScavoldCover.vue";
|
|
557
|
+
import ScavoldBreadcrumb from "scavold/components/ScavoldBreadcrumb.vue";
|
|
558
|
+
|
|
559
|
+
defineOptions( { inheritAttrs: false } );
|
|
560
|
+
</script>
|
|
561
|
+
|
|
562
|
+
<template>
|
|
563
|
+
<ScavoldCover v-bind="$attrs"><slot /></ScavoldCover>
|
|
564
|
+
<ScavoldBreadcrumb v-if="$attrs['data-leading'] != null" />
|
|
565
|
+
</template>
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
```js
|
|
569
|
+
// .vitepress/theme/index.js — the container renders the component by name
|
|
570
|
+
async function enhanceApp( context ) {
|
|
571
|
+
await scavoldEnhanceApp( context );
|
|
572
|
+
context.app.component( "SiteCover", SiteCover );
|
|
573
|
+
}
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
Below a cover the breadcrumb sits inside the content column, so the theme's prose
|
|
577
|
+
styles reach its list; keep them out where they differ from the breadcrumb's own.
|
|
578
|
+
|
|
579
|
+
Visual and reading order stay the same this way, which a reordering stylesheet could
|
|
580
|
+
not promise.
|
|
581
|
+
|
|
507
582
|
---
|
|
508
583
|
|
|
509
584
|
### `<ScavoldPageList>`
|
|
@@ -861,12 +936,13 @@ renders the same picture the way its design asks:
|
|
|
861
936
|
|
|
862
937
|
```js
|
|
863
938
|
const props = defineProps( { ...coverProps } );
|
|
864
|
-
const { src, isVideo, srcset, webpSrcset, sizes, poster, focus, label } = useCover( props );
|
|
939
|
+
const { src, isVideo, srcset, webpSrcset, sizes, poster, focus, label, tone } = useCover( props );
|
|
865
940
|
```
|
|
866
941
|
|
|
867
942
|
`srcset`, `webpSrcset` and `sizes` are filled for an image only; the build provides
|
|
868
|
-
the variants and the dimensions `sizes` is derived from. `
|
|
869
|
-
`coverSizes( width, height )`
|
|
943
|
+
the variants and the dimensions `sizes` is derived from. `tone` is `"light"`, `"dark"`
|
|
944
|
+
or empty, one of `COVER_TONES`. `isVideoUrl( url )` and `coverSizes( width, height )`
|
|
945
|
+
are exported as well.
|
|
870
946
|
|
|
871
947
|
---
|
|
872
948
|
|
|
@@ -1040,6 +1116,12 @@ class names. A flag a component does not declare falls through into the markup a
|
|
|
1040
1116
|
empty attribute — `::: section highlight` renders `<section class="highlight"
|
|
1041
1117
|
data-highlight>`.
|
|
1042
1118
|
|
|
1119
|
+
A container that opens the page — its fence is the first thing in the page body —
|
|
1120
|
+
additionally receives an empty `data-leading` attribute. It is information only and
|
|
1121
|
+
changes nothing by itself; a component or a stylesheet can tell from it that this
|
|
1122
|
+
block stands at the very top. The same fact reaches the layout ahead of the content as
|
|
1123
|
+
`page.leadingContainer` (see [A cover opening the page](#a-cover-opening-the-page)).
|
|
1124
|
+
|
|
1043
1125
|
#### Returns
|
|
1044
1126
|
|
|
1045
1127
|
| Name | Type | Description |
|
|
@@ -7,7 +7,7 @@ import ScavoldImage from "./ScavoldImage.vue";
|
|
|
7
7
|
|
|
8
8
|
const props = defineProps( coverProps );
|
|
9
9
|
|
|
10
|
-
const { src, isVideo, srcset, webpSrcset, sizes, poster, focus, label } = useCover( props );
|
|
10
|
+
const { src, isVideo, srcset, webpSrcset, sizes, poster, focus, label, tone } = useCover( props );
|
|
11
11
|
|
|
12
12
|
const { t } = useScavoldI18n();
|
|
13
13
|
const playLabel = t( "cover.play" );
|
|
@@ -46,7 +46,7 @@ function toggle() {
|
|
|
46
46
|
<div
|
|
47
47
|
v-if="src"
|
|
48
48
|
class="scavold-cover"
|
|
49
|
-
:class="{ 'scavold-cover--video': isVideo }"
|
|
49
|
+
:class="[ { 'scavold-cover--video': isVideo }, tone && `scavold-cover--${tone}` ]"
|
|
50
50
|
:style="style"
|
|
51
51
|
>
|
|
52
52
|
<video
|
package/composables/useCover.js
CHANGED
|
@@ -39,8 +39,17 @@ export const coverProps = {
|
|
|
39
39
|
|
|
40
40
|
/** Alternative text of an image, accessible label of a video. */
|
|
41
41
|
dataLabel: { type: String, default: "" },
|
|
42
|
+
|
|
43
|
+
/** Whether the content on top is meant to be light or dark, see COVER_TONES. */
|
|
44
|
+
dataTone: { type: String, default: "" },
|
|
42
45
|
};
|
|
43
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Tones an author may ask the content on top of a cover to take. The cover only
|
|
49
|
+
* marks its choice; the theme decides what light or dark content looks like.
|
|
50
|
+
*/
|
|
51
|
+
export const COVER_TONES = [ "light", "dark" ];
|
|
52
|
+
|
|
44
53
|
/**
|
|
45
54
|
* Tells whether a URL names a video by its file extension.
|
|
46
55
|
*
|
|
@@ -91,9 +100,10 @@ export function coverSizes( width, height ) {
|
|
|
91
100
|
* - `poster` — still image of a video, or empty string
|
|
92
101
|
* - `focus` — CSS `object-position` value, or empty string
|
|
93
102
|
* - `label` — alternative text or accessible label, or empty string
|
|
103
|
+
* - `tone` — `"light"` or `"dark"` for the content on top, or empty string
|
|
94
104
|
*
|
|
95
105
|
* @param {object} props reactive props from defineProps
|
|
96
|
-
* @returns {{ src, isVideo, srcset, webpSrcset, sizes, poster, focus, label }}
|
|
106
|
+
* @returns {{ src, isVideo, srcset, webpSrcset, sizes, poster, focus, label, tone }}
|
|
97
107
|
*/
|
|
98
108
|
export function useCover( props ) {
|
|
99
109
|
const src = computed( () => props.dataSrc ?? "" );
|
|
@@ -107,5 +117,12 @@ export function useCover( props ) {
|
|
|
107
117
|
const focus = computed( () => props.dataFocus ?? "" );
|
|
108
118
|
const label = computed( () => props.dataLabel ?? "" );
|
|
109
119
|
|
|
110
|
-
|
|
120
|
+
// Anything but a known tone leaves the choice to the theme.
|
|
121
|
+
const tone = computed( () => {
|
|
122
|
+
const value = String( props.dataTone ?? "" ).trim().toLowerCase();
|
|
123
|
+
|
|
124
|
+
return COVER_TONES.includes( value ) ? value : "";
|
|
125
|
+
} );
|
|
126
|
+
|
|
127
|
+
return { src, isVideo, srcset, webpSrcset, sizes, poster, focus, label, tone };
|
|
111
128
|
}
|
package/index.d.ts
CHANGED
|
@@ -37,6 +37,9 @@ export module Scavold {
|
|
|
37
37
|
|
|
38
38
|
interface AugmentedPageData extends PageData {
|
|
39
39
|
hierarchy: HierarchyNode;
|
|
40
|
+
|
|
41
|
+
/** Name of the container the page opens with, e.g. `"cover"`, or null when it opens with anything else. Known before the content renders, so a layout can arrange its own parts around it. */
|
|
42
|
+
leadingContainer: string | null;
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
interface MenuItem {
|
package/lib/config.js
CHANGED
|
@@ -8,7 +8,7 @@ import { extractFrontmatterMediaSrcs } from "./excerpt.js";
|
|
|
8
8
|
import { DEFAULT_FEED_LIMIT, collectFeedPages, renderRss } from "./feed.js";
|
|
9
9
|
import { useMedia } from "./media.js";
|
|
10
10
|
import { patchRenderer } from "./markdown.js";
|
|
11
|
-
import { extractContainerMediaSrcs, mediaPropsOf, registerContainers, resolveContainerMap } from "./containers.js";
|
|
11
|
+
import { extractContainerMediaSrcs, leadingContainerOf, mediaPropsOf, registerContainers, resolveContainerMap } from "./containers.js";
|
|
12
12
|
import { buildSectionManifest, writeSectionManifest } from "./sectionManifest.js";
|
|
13
13
|
import { isExternalUrl, servableRedirectTarget } from "./redirectTarget.js";
|
|
14
14
|
import { assertUniquePageKeys } from "./pageKeys.js";
|
|
@@ -686,7 +686,21 @@ export async function augmentConfig( rawConfig, options = {} ) {
|
|
|
686
686
|
url => media.collectImage( url ),
|
|
687
687
|
);
|
|
688
688
|
|
|
689
|
-
|
|
689
|
+
// A layout renders its own parts — a breadcrumb, say — before the page
|
|
690
|
+
// content, so whether the page opens with a container has to be known before
|
|
691
|
+
// that content is rendered. Read from the source rather than the rendered
|
|
692
|
+
// page, which does not exist yet when the layout needs it.
|
|
693
|
+
let leadingContainer = null;
|
|
694
|
+
|
|
695
|
+
try {
|
|
696
|
+
leadingContainer = leadingContainerOf(
|
|
697
|
+
readFileSync( join( sourceFolder( resolvedConfig ), pageData.filePath ), "utf-8" ),
|
|
698
|
+
);
|
|
699
|
+
} catch {
|
|
700
|
+
// a page without a source file of its own, e.g. a generated one
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
return { hierarchy, leadingContainer };
|
|
690
704
|
},
|
|
691
705
|
markdown: {
|
|
692
706
|
config( md ) {
|
package/lib/containers.js
CHANGED
|
@@ -55,7 +55,7 @@ function resolveTag( name, map ) {
|
|
|
55
55
|
* @param {string} containerName the original container name from markdown
|
|
56
56
|
* @returns {string}
|
|
57
57
|
*/
|
|
58
|
-
function renderToken( tag, token, containerName, { mediaProps = {}, resolveMedia, resolveImage } = {} ) {
|
|
58
|
+
function renderToken( tag, token, containerName, { mediaProps = {}, resolveMedia, resolveImage } = {}, leading = false ) {
|
|
59
59
|
if ( token.nesting !== 1 ) {
|
|
60
60
|
return `</${tag}>\n`;
|
|
61
61
|
}
|
|
@@ -107,6 +107,13 @@ function renderToken( tag, token, containerName, { mediaProps = {}, resolveMedia
|
|
|
107
107
|
|
|
108
108
|
attrs.push( `data-container="${containerName}"` );
|
|
109
109
|
|
|
110
|
+
// A container opening the page is marked as such, so a theme can tell a cover at
|
|
111
|
+
// the top of a page from one further down. It is information only; see
|
|
112
|
+
// leadingContainerOf() for the page-level counterpart.
|
|
113
|
+
if ( leading ) {
|
|
114
|
+
attrs.push( 'data-leading=""' );
|
|
115
|
+
}
|
|
116
|
+
|
|
110
117
|
if ( classes ) {
|
|
111
118
|
attrs.push( `class="${classes}"` );
|
|
112
119
|
}
|
|
@@ -133,7 +140,7 @@ export function registerContainers( md, containerMap, { warn = console.warn, med
|
|
|
133
140
|
|
|
134
141
|
for ( const [ name, tag ] of Object.entries( containerMap ) ) {
|
|
135
142
|
md.use( ContainerPlugin, name, {
|
|
136
|
-
render: ( tokens, index ) => renderToken( tag, tokens[index], name, renderOptions ),
|
|
143
|
+
render: ( tokens, index ) => renderToken( tag, tokens[index], name, renderOptions, index === 0 ),
|
|
137
144
|
} );
|
|
138
145
|
}
|
|
139
146
|
|
|
@@ -164,11 +171,31 @@ export function registerContainers( md, containerMap, { warn = console.warn, med
|
|
|
164
171
|
);
|
|
165
172
|
}
|
|
166
173
|
|
|
167
|
-
return renderToken( resolveTag( name, containerMap ), tokens[index], name, renderOptions );
|
|
174
|
+
return renderToken( resolveTag( name, containerMap ), tokens[index], name, renderOptions, index === 0 );
|
|
168
175
|
},
|
|
169
176
|
} );
|
|
170
177
|
}
|
|
171
178
|
|
|
179
|
+
/**
|
|
180
|
+
* Names the container a page opens with, i.e. the one whose fence is the first thing
|
|
181
|
+
* in the page body, or null when the page opens with anything else. Follows
|
|
182
|
+
* markdown-it: the front matter does not count, blank lines do not either, and a
|
|
183
|
+
* fence may be indented by up to three spaces.
|
|
184
|
+
*
|
|
185
|
+
* This is the page-level counterpart of the `data-leading` attribute: a layout
|
|
186
|
+
* renders its own parts before the page content, so it has to know in advance.
|
|
187
|
+
*
|
|
188
|
+
* @param {string} source markdown source of one page, front matter included
|
|
189
|
+
* @returns {string|null}
|
|
190
|
+
*/
|
|
191
|
+
export function leadingContainerOf( source ) {
|
|
192
|
+
const body = String( source ?? "" ).replace( /^---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/, "" );
|
|
193
|
+
const first = body.split( /\r?\n/ ).find( line => line.trim() !== "" ) ?? "";
|
|
194
|
+
const match = /^ {0,3}:{3,}\s*(.*)$/.exec( first );
|
|
195
|
+
|
|
196
|
+
return match ? containerNameOf( match[1] ) || null : null;
|
|
197
|
+
}
|
|
198
|
+
|
|
172
199
|
/**
|
|
173
200
|
* Extracts the container name from a container fence's info string, i.e. the first
|
|
174
201
|
* word after the colons. Returns an empty string when it is not a usable name.
|
package/lib/sectionManifest.js
CHANGED
|
@@ -88,6 +88,12 @@ export const BUILTIN_SECTIONS = {
|
|
|
88
88
|
label: "Description",
|
|
89
89
|
hint: "Alternative text of the image, or what the video shows. Leave empty when it is decoration only.",
|
|
90
90
|
},
|
|
91
|
+
tone: {
|
|
92
|
+
type: "enum",
|
|
93
|
+
label: "Content on top",
|
|
94
|
+
values: [ "light", "dark" ],
|
|
95
|
+
hint: "\"light\" over a dark picture, \"dark\" over a bright one. Left unset, the site's design decides.",
|
|
96
|
+
},
|
|
91
97
|
},
|
|
92
98
|
},
|
|
93
99
|
|
package/package.json
CHANGED
package/scripts/check-fixture.js
CHANGED
|
@@ -297,6 +297,12 @@ const covers = cover.split( /<div class="scavold-cover[ "]/ ).slice( 1 );
|
|
|
297
297
|
const [ coverImage = "", coverVideo = "" ] = covers;
|
|
298
298
|
|
|
299
299
|
expect( covers.length === 2, "renders both covers of the page", `found ${covers.length}` );
|
|
300
|
+
expect( /<div class="scavold-cover[ "][^>]*\sdata-leading[\s=>]/.test( cover ) && cover.match( /\sdata-leading[\s=>]/g )?.length === 1,
|
|
301
|
+
"marks the cover opening the page, and only that one" );
|
|
302
|
+
expect( cover.includes( '<main data-leading-container="cover">' ),
|
|
303
|
+
"tells the layout before the content renders that the page opens with a cover" );
|
|
304
|
+
expect( !/<main[^>]*data-leading-container/.test( built( "media.html" ) ),
|
|
305
|
+
"tells it nothing on a page that opens with anything else" );
|
|
300
306
|
// The variants, not just the widest one: a cover is the largest image of a page and
|
|
301
307
|
// must not cost a phone the full 1920px file.
|
|
302
308
|
expect( /<source type="image\/webp" srcset="[^"]*wide--320w-[0-9a-f]+\.webp 320w[^"]*wide--1920w-[0-9a-f]+\.webp 1920w"/.test( coverImage ),
|
|
@@ -315,6 +321,9 @@ expect( /class="scavold-cover__overlay"[^>]*>\s*(?:<!--\[-->)?\s*<h1[^>]*>Over t
|
|
|
315
321
|
const coverVideoTag = tags( coverVideo, "video" )[0] ?? "";
|
|
316
322
|
|
|
317
323
|
expect( coverVideo.startsWith( "scavold-cover--video" ), "tells a video cover by its file type" );
|
|
324
|
+
// A mark for the theme to style, nothing more.
|
|
325
|
+
expect( /^scavold-cover--light"/.test( coverImage ), "marks the tone asked for the content on top" );
|
|
326
|
+
expect( !/scavold-cover--(light|dark)/.test( coverVideo ), "marks no tone where none is asked for" );
|
|
318
327
|
expect( !cover.includes( "data-poster-srcset" ), "keeps the variants of a still image out of the markup" );
|
|
319
328
|
expect( /src="\/media\/clip\.mp4"/.test( coverVideoTag ) && /poster="\/media\/wide--\d+w-[0-9a-f]+\.jpg"/.test( coverVideoTag ),
|
|
320
329
|
"resolves a cover video and its still image to their published URLs" );
|