diff options
-rw-r--r-- | src/content/dependencies/generateCoverArtwork.js | 24 | ||||
-rw-r--r-- | src/content/dependencies/image.js | 78 | ||||
-rw-r--r-- | src/content/dependencies/linkThing.js | 5 | ||||
-rw-r--r-- | src/static/js/client/image-overlay.js | 3 |
4 files changed, 88 insertions, 22 deletions
diff --git a/src/content/dependencies/generateCoverArtwork.js b/src/content/dependencies/generateCoverArtwork.js index 89b66ce0..616b3c95 100644 --- a/src/content/dependencies/generateCoverArtwork.js +++ b/src/content/dependencies/generateCoverArtwork.js @@ -122,6 +122,30 @@ export default { thumb: 'medium', reveal: true, link: true, + + responsiveThumb: true, + responsiveSizes: + // No clamp(), min(), or max() here because Safari. + // The boundaries here are mostly experimental, apart from + // the ones which flat-out switch layouts. + + // Layout - Thin (phones) + // Most of viewport width + '(max-width: 600px) 90vw,\n' + + + // Layout - Medium + // Sidebar is hidden; content area is by definition + // most of the viewport + '(max-width: 640px) 220px,\n' + + '(max-width: 800px) 36vw,\n' + + '(max-width: 850px) 280px,\n' + + + // Layout - Wide + // Sidebar is visible; content area has its own maximum + // Assume the sidebar is at minimum width + '(max-width: 880px) 220px,\n' + + '(max-width: 1050pz) calc(0.40 * (90vw - 150px - 10px)),\n' + + '280px', }), slots.showOriginDetails && diff --git a/src/content/dependencies/image.js b/src/content/dependencies/image.js index 1b6b08dd..d979b0bc 100644 --- a/src/content/dependencies/image.js +++ b/src/content/dependencies/image.js @@ -28,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}, @@ -199,31 +201,29 @@ export default { // 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 @@ -239,11 +239,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( @@ -252,10 +295,7 @@ export default { } const images = { - displayStatic: - html.tag('img', - imgAttributes, - {src: displaySrc}), + displayStatic: displayStaticImg, displayLazy: slots.lazy && diff --git a/src/content/dependencies/linkThing.js b/src/content/dependencies/linkThing.js index 7784afe7..166a857d 100644 --- a/src/content/dependencies/linkThing.js +++ b/src/content/dependencies/linkThing.js @@ -77,14 +77,15 @@ export default { const linkAttributes = slots.attributes; const wrapperAttributes = html.attributes(); + const name = + relations.name.slot('preferShortName', slots.preferShortName); + const showShortName = slots.preferShortName && !data.nameText && data.nameShort && data.nameShort !== data.name; - const name = relations.name; - const showWikiTooltip = (slots.tooltipStyle === 'auto' ? showShortName diff --git a/src/static/js/client/image-overlay.js b/src/static/js/client/image-overlay.js index 6809726a..0595bff7 100644 --- a/src/static/js/client/image-overlay.js +++ b/src/static/js/client/image-overlay.js @@ -147,7 +147,8 @@ function getImageLinkDetails(imageLink) { a.href, embeddedSrc: - img?.src ?? + img?.src || + img?.currentSrc || a.dataset.embedSrc, originalFileSize: |