-
-
Notifications
You must be signed in to change notification settings - Fork 54
/
eleventy-image.webc
131 lines (106 loc) · 3.65 KB
/
eleventy-image.webc
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<!---
Supported attribute list:
* src (required)
* width
* formats
* url-path
* output-dir
<img
webc:is="eleventy-image"
src="./src/img/possum-geri.png"
alt="The possum is Eleventy’s mascot"
width="222, 350"
class="some-custom-class"
sizes="(min-width: 43.75em) 100px, 15vw">
Alternative attribute formats:
:width="[222, 350]"
formats="avif,webp,jpeg"
:formats="['avif', 'webp', 'jpeg']"
--->
<script webc:type="js">
const path = require("path");
// TODO expose this for re-use in a provided shortcode.
async function imagePlugin(attributes, globalPluginOptions) {
if(!attributes.src) {
throw new Error("Missing `src` attribute on <eleventy-image>");
}
// TODO allow remote optimization automatically on full urls
let imagePackage;
let defaultGlobalAttributes;
if(globalPluginOptions) {
defaultGlobalAttributes = globalPluginOptions.defaultAttributes;
delete globalPluginOptions.defaultAttributes;
imagePackage = globalPluginOptions.packages?.image;
delete globalPluginOptions.packages;
}
if(!imagePackage) {
imagePackage = require("@11ty/eleventy-img");
}
let instanceOptions = {};
// Note that multiple widths require a `sizes`
if(attributes.width) {
if(typeof attributes.width === "string") {
instanceOptions.widths = attributes.width.split(",").map(entry => parseInt(entry, 10));
delete attributes.width;
} else if(Array.isArray(attributes.width)) {
instanceOptions.widths = attributes.width;
delete attributes.width;
}
}
if(attributes.formats) {
if(typeof attributes.formats === "string") {
instanceOptions.formats = attributes.formats.split(",").map(entry => entry.trim());
delete attributes.formats;
} else if(Array.isArray(attributes.formats)) {
instanceOptions.formats = attributes.formats;
delete attributes.formats;
}
}
// These defaults are set only if addPlugin was **not** called:
if(!globalPluginOptions) {
// Using eleventy.directories global data (Eleventy 2.0.2+)
if(eleventy.directories) {
instanceOptions.urlPath = "/img/";
// write to output folder by default
instanceOptions.outputDir = path.join(eleventy.directories.output, instanceOptions.urlPath);
}
}
// Overrides via attributes (hopefully you don’t need these)
if(attributes.urlPath) {
instanceOptions.urlPath = attributes.urlPath;
delete attributes.urlPath;
if(eleventy.directories && !attributes.outputDir) {
// use output folder if available (Eleventy v2.0.2+)
instanceOptions.outputDir = path.join(eleventy.directories.output, instanceOptions.urlPath);
}
}
if(attributes.outputDir) {
instanceOptions.outputDir = attributes.outputDir;
delete attributes.outputDir;
}
let options = Object.assign({}, globalPluginOptions, instanceOptions);
// see Util.addConfig
if(globalPluginOptions.eleventyConfig) {
Object.defineProperty(options, "eleventyConfig", {
value: globalPluginOptions.eleventyConfig,
enumerable: false,
});
}
let metadata = await imagePackage(src, options);
let imageAttributes = Object.assign({}, defaultGlobalAttributes, attributes);
// You bet we throw an error on missing alt in `imageAttributes` (alt="" works okay)
return imagePackage.generateHTML(metadata, imageAttributes);
};
(async () => {
let globalPluginOptions;
// fetch global options from from addPlugin call
if(typeof __private_eleventyImageConfigurationOptions === "function") {
globalPluginOptions = __private_eleventyImageConfigurationOptions();
}
if(!("filterPublicAttributes" in webc)) {
throw new Error("The <eleventy-image> WebC component requires WebC v0.10.1+");
}
let attributes = webc.filterPublicAttributes(webc.attributes);
return imagePlugin(attributes, globalPluginOptions);
})();
</script>