diff --git a/src/generate-html.js b/src/generate-html.js index e5c21b1..dd47d86 100644 --- a/src/generate-html.js +++ b/src/generate-html.js @@ -25,7 +25,7 @@ function generateSrcset(metadataFormatEntry) { ] } */ -function generateObject(metadata, userDefinedImgAttributes = {}, userDefinedPictureAttributes = {}, options = {}) { +function generateObject(metadata, userDefinedImgAttributes = {}, userDefinedPictureAttributes = {}, htmlOptions = {}) { let imgAttributes = Object.assign({}, userDefinedImgAttributes); let pictureAttributes = Object.assign({}, userDefinedPictureAttributes); @@ -71,14 +71,14 @@ function generateObject(metadata, userDefinedImgAttributes = {}, userDefinedPict imgAttributes.src = lowsrc[0].url; - if(options.fallback === "largest" || options.fallback === undefined) { + if(htmlOptions.fallback === "largest" || htmlOptions.fallback === undefined) { imgAttributes.width = lowsrc[lowsrc.length - 1].width; imgAttributes.height = lowsrc[lowsrc.length - 1].height; - } else if(options.fallback === "smallest") { + } else if(htmlOptions.fallback === "smallest") { imgAttributes.width = lowsrc[0].width; imgAttributes.height = lowsrc[0].height; } else { - throw new Error("Invalid `fallback` option specified. 'largest' and 'smallest' are supported. Received: " + options.fallback); + throw new Error("Invalid `fallback` option specified. 'largest' and 'smallest' are supported. Received: " + htmlOptions.fallback); } let imgAttributesWithoutSizes = Object.assign({}, imgAttributes); @@ -182,12 +182,14 @@ function mapObjectToHTML(tagName, attrs = {}) { return `<${tagName}${attrHtml ? ` ${attrHtml}` : ""}>`; } -function generateHTML(metadata, attributes = {}, optionsOverride = {}) { - let options = Object.assign({}, metadata?.eleventyImage?.options, optionsOverride); - let isInline = options.whitespaceMode !== "block"; +function generateHTML(metadata, attributesOverride = {}, htmlOptionsOverride = {}) { + let attributes = Object.assign({}, metadata?.eleventyImage?.htmlOptions?.imgAttributes, attributesOverride); + let htmlOptions = Object.assign({}, metadata?.eleventyImage?.htmlOptions, htmlOptionsOverride); + + let isInline = htmlOptions.whitespaceMode !== "block"; let markup = []; - let obj = generateObject(metadata, attributes, options.pictureAttributes, options); + let obj = generateObject(metadata, attributes, htmlOptions.pictureAttributes, htmlOptions); for(let tag in obj) { markup.push(mapObjectToHTML(tag, obj[tag])); diff --git a/src/global-options.js b/src/global-options.js index 3f88577..05f87e0 100644 --- a/src/global-options.js +++ b/src/global-options.js @@ -76,9 +76,20 @@ const DEFAULTS = { // operate on Sharp instance manually. transform: undefined, - // the will use the largest dimensions for width/height (when multiple output widths are specified) - // see https://github.com/11ty/eleventy-img/issues/63 - fallback: "largest", // or "smallest" + // return HTML from generateHTML directly + return: "object", // or "html" + + // Defaults used when generateHTML is called from a result set + htmlOptions: { + imgAttributes: {}, + pictureAttributes: {}, + + whitespaceMode: "inline", // "block" + + // the will use the largest dimensions for width/height (when multiple output widths are specified) + // see https://github.com/11ty/eleventy-img/issues/63 + fallback: "largest", // or "smallest" + }, // v5.0.0 Removed `extensions`, option to override output format with new file extension. It wasn’t being used anywhere or documented. // v6.0.0, removed `useCacheValidityInHash: true` see https://github.com/11ty/eleventy-img/issues/146#issuecomment-2555741376 diff --git a/src/image.js b/src/image.js index b6d2ed8..c3d387b 100644 --- a/src/image.js +++ b/src/image.js @@ -10,6 +10,7 @@ const { Fetch } = require("@11ty/eleventy-fetch"); const Util = require("./util.js"); const ImagePath = require("./image-path.js"); +const generateHTML = require("./generate-html.js"); const GLOBAL_OPTIONS = require("./global-options.js").defaults; const { existsCache, memCache, diskCache } = require("./caches.js"); @@ -242,7 +243,7 @@ class Image { return []; } - _transformRawFiles(files = []) { + #transformRawFiles(files = []) { let byType = {}; for(let file of files) { if(!byType[file.format]) { @@ -290,11 +291,31 @@ class Image { } } - this.addHiddenMetadata(byType); - return byType; } + #finalizeResults(results = {}) { + // used when results are passed to generate HTML, we maintain some internal metadata about the options used. + Object.defineProperty(results, "eleventyImage", { + enumerable: false, + writable: false, + value: { + htmlOptions: { + whitespaceMode: this.options.htmlOptions?.whitespaceMode, + imgAttributes: this.options.htmlOptions?.imgAttributes, + pictureAttributes: this.options.htmlOptions?.pictureAttributes, + fallback: this.options.htmlOptions?.fallback, + }, + } + }); + + if(this.options.return === "html") { + return generateHTML(results); + } + + return results; + } + getSharpOptionsForFormat(format) { if(format === "webp") { return this.options.sharpWebpOptions; @@ -511,7 +532,7 @@ class Image { } } - return this._transformRawFiles(results); + return this.#transformRawFiles(results); } getOutputSize(contents, filePath) { @@ -565,6 +586,7 @@ class Image { let outputFilePromises = []; let fullStats = this.getFullStats(metadata); + for(let outputFormat in fullStats) { for(let stat of fullStats[outputFormat]) { if(this.isOutputCached(stat.outputPath, input)) { @@ -679,22 +701,7 @@ class Image { } } - return Promise.all(outputFilePromises).then(files => this._transformRawFiles(files)); - } - - addHiddenMetadata(results) { - // used when results are passed to generate HTML, we maintain some internal metadata about the options used. - Object.defineProperty(results, "eleventyImage", { - enumerable: false, - writable: false, - value: { - options: { - pictureAttributes: this.options.pictureAttributes, - whitespaceMode: this.options.whitespaceMode, - fallback: this.options.fallback, - }, - } - }); + return Promise.all(outputFilePromises).then(files => this.#finalizeResults(this.#transformRawFiles(files))); } async getStatsOnly() { diff --git a/test/test-markup.js b/test/test-markup.js index 1805e3a..e60cff4 100644 --- a/test/test-markup.js +++ b/test/test-markup.js @@ -346,7 +346,9 @@ test("Image markup with smallest fallback dimensions", async t => { dryRun: true, widths: [300, "auto"], formats: ["auto"], - fallback: "smallest", + htmlOptions: { + fallback: "smallest", + }, }); t.is(generateHTML(results, { @@ -354,3 +356,40 @@ test("Image markup with smallest fallback dimensions", async t => { sizes: "100vw" }), ``); }); + +test("return: html to ", async t => { + let html = await eleventyImage("./test/bio-2017.jpg", { + dryRun: true, + formats: ["auto"], + return: "html", + + // passed to generateHTML + htmlOptions: { + imgAttributes: { + alt: "", + }, + }, + }); + + t.is(html, ``); +}); + +test("return: html to ", async t => { + let html = await eleventyImage("./test/bio-2017.jpg", { + dryRun: true, + return: "html", + + // passed to generateHTML + htmlOptions: { + imgAttributes: { + alt: "", + class: "inner", + }, + pictureAttributes: { + class: "outer" + } + }, + }); + + t.is(html, ``); +});