diff options
Diffstat (limited to 'src/content/dependencies/image.js')
| -rw-r--r-- | src/content/dependencies/image.js | 119 |
1 files changed, 71 insertions, 48 deletions
diff --git a/src/content/dependencies/image.js b/src/content/dependencies/image.js index bf47b14f..af4b7fdd 100644 --- a/src/content/dependencies/image.js +++ b/src/content/dependencies/image.js @@ -2,20 +2,6 @@ import {logWarn} from '#cli'; import {empty} from '#sugar'; export default { - extraDependencies: [ - 'checkIfImagePathHasCachedThumbnails', - 'getDimensionsOfImagePath', - 'getSizeOfMediaFile', - 'getThumbnailEqualOrSmaller', - 'getThumbnailsAvailableForDimensions', - 'html', - 'language', - 'missingImagePaths', - 'to', - ], - - contentDependencies: ['generateColorStyleAttribute'], - relations: (relation, _artwork) => ({ colorStyle: relation('generateColorStyleAttribute'), @@ -42,6 +28,8 @@ export default { slots: { thumb: {type: 'string'}, + responsiveThumb: {type: 'boolean', default: false}, + responsiveSizes: {type: 'string'}, reveal: {type: 'boolean', default: true}, lazy: {type: 'boolean', default: false}, @@ -60,6 +48,12 @@ export default { mutable: false, }, + // Added to the <img>. + imgAttributes: { + type: 'attributes', + mutable: false, + }, + // Added to the <img> itself. alt: {type: 'string'}, @@ -114,12 +108,11 @@ export default { // src string directly when a parts-formed path *is* available seems wrong. // It should be possible to do urls.from(slots.path[0]).to(...slots.path), // for example, but will require reworking the control flow here a little. - let mediaSrc = null; + let mediaSrc = decodeURIComponent(originalSrc); if (originalSrc.startsWith(to('media.root'))) { - mediaSrc = - originalSrc - .slice(to('media.root').length) - .replace(/^\//, ''); + mediaSrc = mediaSrc + .slice(to('media.root').length) + .replace(/^\//, ''); } const isMissingImageFile = @@ -141,6 +134,8 @@ export default { const imgAttributes = html.attributes([ {class: 'image'}, + slots.imgAttributes, + slots.alt && {alt: slots.alt}, dimensions && @@ -189,47 +184,35 @@ export default { mediaSrc && checkIfImagePathHasCachedThumbnails(mediaSrc); - // Warn for images that *should* have cached thumbnail information but are - // missing from the thumbs cache. - if ( - slots.thumb && - !hasThumbnails && - !mediaSrc.endsWith('.gif') - ) { - logWarn`No thumbnail info cached: ${mediaSrc} - displaying original image here (instead of ${slots.thumb})`; - } - let displaySrc = originalSrc; // This is only distinguished from displaySrc by being a thumbnail, // so it won't be set if thumbnails aren't available. let revealSrc = null; + let originalDimensions; + let availableThumbs; + let selectedThumbtack; + + const getThumbSrc = (thumbtack) => + to('thumb.path', mediaSrc.replace(/\.(png|jpg)$/, `.${thumbtack}.jpg`)); + // If thumbnails are available *and* being used, calculate thumbSrc, // and provide some attributes relevant to the large image overlay. if (hasThumbnails && slots.thumb) { - const selectedSize = + selectedThumbtack = getThumbnailEqualOrSmaller(slots.thumb, mediaSrc); - const mediaSrcJpeg = - mediaSrc.replace(/\.(png|jpg)$/, `.${selectedSize}.jpg`); - displaySrc = - to('thumb.path', mediaSrcJpeg); + getThumbSrc(selectedThumbtack); if (willReveal) { - const miniSize = - getThumbnailEqualOrSmaller('mini', mediaSrc); - - const mediaSrcJpeg = - mediaSrc.replace(/\.(png|jpg)$/, `.${miniSize}.jpg`); - revealSrc = - to('thumb.path', mediaSrcJpeg); + getThumbSrc(getThumbnailEqualOrSmaller('mini', mediaSrc)); } - const originalDimensions = getDimensionsOfImagePath(mediaSrc); - const availableThumbs = getThumbnailsAvailableForDimensions(originalDimensions); + originalDimensions = getDimensionsOfImagePath(mediaSrc); + availableThumbs = getThumbnailsAvailableForDimensions(originalDimensions); const fileSize = (willLink && mediaSrc @@ -245,11 +228,54 @@ export default { !empty(availableThumbs) && {'data-thumbs': availableThumbs - .map(([name, size]) => `${name}:${size}`) + .map(([tack, size]) => `${tack}:${size}`) .join(' ')}, ]); } + let displayStaticImg = + html.tag('img', + imgAttributes, + {src: displaySrc}); + + if (hasThumbnails && slots.responsiveThumb) responsive: { + if (slots.lazy) { + logWarn`${'responsiveThumb'} and ${'lazy'} are used together, but not compatible`; + break responsive; + } + + if (!slots.thumb) { + logWarn`${'responsiveThumb'} must be used alongside a default ${'thumb'}`; + break responsive; + } + + const srcset = [ + // Never load the original source, which might be a very large + // uncompressed file. Bah! + /* [originalSrc, `${Math.min(...originalDimensions)}w`], */ + + ...availableThumbs.map(([tack, size]) => + [getThumbSrc(tack), `${Math.floor(0.95 * size)}w`]), + + // fallback + [displaySrc], + ].map(line => line.join(' ')).join(',\n'); + + displayStaticImg = + html.tag('img', + imgAttributes, + + {sizes: + (slots.responsiveSizes.match(/(?=(?:,|^))\s*\S/) + // slot provided fallback size + ? slots.responsiveSizes + // default fallback size + : slots.responsiveSizes + ',\n' + + new Map(availableThumbs).get(selectedThumbtack) + 'px')}, + + {srcset}); + } + if (!displaySrc) { return ( prepare( @@ -258,10 +284,7 @@ export default { } const images = { - displayStatic: - html.tag('img', - imgAttributes, - {src: displaySrc}), + displayStatic: displayStaticImg, displayLazy: slots.lazy && |