Skip to content

Commit

Permalink
On #259 when an image errors and eleventy:optional=keep revert to the…
Browse files Browse the repository at this point in the history
… original source attribute. Fixes #257
  • Loading branch information
zachleat committed Dec 13, 2024
1 parent af23825 commit a7c949c
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 6 deletions.
14 changes: 10 additions & 4 deletions src/image-attrs-to-posthtml-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,28 @@ async function imageAttributesToPosthtmlNode(attributes, instanceOptions, global
Util.addConfig(globalPluginOptions.eleventyConfig, options);

let metadata = await eleventyImage(attributes.src, options);
cleanAttrs(attributes);

let imageAttributes = Object.assign({}, globalPluginOptions.defaultAttributes, attributes);

// You bet we throw an error on missing alt in `imageAttributes` (alt="" works okay)
let obj = await eleventyImage.generateObject(metadata, imageAttributes);
return convertToPosthtmlNode(obj);
}

function cleanTag(node) {
// Delete all prefixed attributes
for(let key in node?.attrs) {
function cleanAttrs(attrs = {}) {
for(let key in attrs) {
if(key.startsWith(ATTR_PREFIX)) {
delete node?.attrs?.[key];
delete attrs?.[key];
}
}
}

function cleanTag(node) {
// Delete all prefixed attributes
cleanAttrs(node?.attrs);
}

function isIgnored(node) {
return node?.attrs && node?.attrs?.[ATTR.IGNORE] !== undefined;
}
Expand Down
15 changes: 14 additions & 1 deletion src/transform-plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ const { imageAttributesToPosthtmlNode, getOutputDirectory, cleanTag, isIgnored,
const { getGlobalOptions } = require("./global-options.js");
const { eleventyImageOnRequestDuringServePlugin } = require("./on-request-during-serve-plugin.js");

const PLACEHOLDER_DATA_URI = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=";

const ATTRS = {
ORIGINAL_SOURCE: "eleventy:internal_original_src",
};

function transformTag(context, node, opts) {
let originalSource = node.attrs?.src;
if(!originalSource) {
Expand All @@ -18,6 +24,9 @@ function transformTag(context, node, opts) {
}, originalSource, {
isViaHtml: true, // this reference came from HTML, so we can decode the file name
});
if(node.attrs.src !== originalSource) {
node.attrs[ATTRS.ORIGINAL_SOURCE] = originalSource;
}

let instanceOptions = {};

Expand Down Expand Up @@ -60,10 +69,14 @@ function transformTag(context, node, opts) {
}, (error) => {
if(isOptional(node) || !opts.failOnError) {
if(isOptional(node, "keep")) {
// replace with the original source value, no image transformation is taking place
if(node.attrs[ATTRS.ORIGINAL_SOURCE]) {
node.attrs.src = node.attrs[ATTRS.ORIGINAL_SOURCE];
}
// leave as-is, likely 404 when a user visits the page
} else if(isOptional(node, "placeholder")) {
// transparent png
node.attrs.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=";
node.attrs.src = PLACEHOLDER_DATA_URI;
} else if(isOptional(node)) {
delete node.attrs.src;
}
Expand Down
Binary file added test/car.mp4
Binary file not shown.
16 changes: 15 additions & 1 deletion test/transform-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ test("Using the transform plugin, data URI #238", async t => {
t.is(results[0].content, `<img src="data:image/" alt="My ugly mug">`);
});


test("Using the transform plugin (override options)", async t => {
let elev = new Eleventy( "test", "test/_site", {
config: eleventyConfig => {
Expand Down Expand Up @@ -325,3 +324,18 @@ test("Don’t throw an error when failOnError: false and `eleventy:optional=plac
let results = await elev.toJSON();
t.is(normalizeEscapedPaths(results[0].content), `<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNgYAAAAAMAASsJTYQAAAAASUVORK5CYII=" alt="My ugly mug">`);
});

test("Using the transform plugin, <img src=video.mp4> #257", async t => {
let elev = new Eleventy( "test", "test/_site", {
config: eleventyConfig => {
eleventyConfig.addTemplate("virtual.html", `<img src="car.mp4" alt="My ugly mug" eleventy:optional="keep">`);

eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
dryRun: true // don’t write image files!
});
}
});

let results = await elev.toJSON();
t.is(results[0].content, `<img src="car.mp4" alt="My ugly mug">`);
});

0 comments on commit a7c949c

Please sign in to comment.