Skip to content
This repository has been archived by the owner on Dec 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #322 from brandonbk/embedded-picture
Browse files Browse the repository at this point in the history
Add <picture> support
  • Loading branch information
solocommand authored Jun 7, 2022
2 parents 48484ad + 2962a7d commit f69a072
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

p [data-embed-type] {
margin: $theme-embedded-media-margin;
text-align: center;
}

[data-embed-type][data-embed-align="left"] {
Expand All @@ -40,8 +41,6 @@ p [data-embed-type] {
}

[data-embed-type] img {
width: 100%;
min-width: 100%;
max-width: 100%;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $ const withCaption = defaultValue(input.withCaption, true);
$ const withCredit = defaultValue(input.withCredit, true);
$ const withDisplayName = defaultValue(input.withDisplayName, true);

$ const fluidWidth = defaultValue(input.fluidWidth, 700);
$ const fluidWidth = defaultValue(input.fluidWidth, 880);
$ const alignedWidth = defaultValue(input.alignedWidth, 300);
$ const shouldFill = defaultValue(input.shouldFill, false);
$ const lazyload = defaultValue(input.lazyload, false);
Expand All @@ -31,7 +31,7 @@ $ if (["left", "right"].includes(display)) {
}
$ modifiers.push(`aligned-${display}`);

$ const maxWidth = input.maxWidth || 700;
$ const maxWidth = input.maxWidth || 880;
$ const fluid = !["left", "right"].includes(display);
$ if (fluid) modifiers.push("fluid");
$ if (fluid && aspectRatio === "16x9") modifiers.push("fluid-16by9")
Expand All @@ -47,12 +47,30 @@ $ if (fluid) {
imageOptions.w = alignedWidth;
};

$ const src = buildImgixUrl(image.src, imageOptions);
$ const srcset = [src, `${buildImgixUrl(src, { dpr: 2 })} 2x`];
$ const srcMid = buildImgixUrl(src, { w: 700 });
$ const srcsetMid = [srcMid, `${buildImgixUrl(srcMid, { dpr: 2 })} 2x`];
$ const srcMin = buildImgixUrl(src, { w: 400 });
$ const srcsetMin = [srcMin, `${buildImgixUrl(srcMin, { dpr: 2 })} 2x`];
$ const sources = [];
$ if (fluid) {
sources.push(
{ srcset: srcset, media: "(min-width: 900px)" },
{ srcset: srcsetMid, media: "(min-width: 576px)" }
);
} else {
const alignedSrc = buildImgixUrl(src, { w: alignedWidth });
const alignedSrcset = [alignedSrc, `${buildImgixUrl(alignedSrc, { dpr: 2 })} 2x`];
sources.push(
{ srcset: alignedSrcset, media: "(min-width: 576px)" }
);
};

$ const imageAttrs = {};
$ if (image.id) imageAttrs["data-image-id"] = image.id;

<if(hasImage && display !== "none")>
$ const src = buildImgixUrl(image.src, imageOptions);
$ const srcset = [`${buildImgixUrl(src, { dpr: 2 })} 2x`];

<marko-web-block
name=blockName
Expand All @@ -62,14 +80,19 @@ $ if (image.id) imageAttrs["data-image-id"] = image.id;
<marko-web-image-display-name block-name=blockName obj=image />
</if>
<div class=`${blockName}__wrapper`>
<marko-web-img
src=src
srcset=srcset
alt=image.alt
class=`${blockName}__image`
attrs=imageAttrs
lazyload=lazyload
/>
<marko-web-picture>
<for|s| of=sources>
<@source srcset=s.srcset media=s.media />
</for>
<@image
src=srcMin
srcset=srcsetMin
class=[`${blockName}__image`]
alt=image.alt
attrs=imageAttrs
lazyload=lazyload
/>
</marko-web-picture>
</div>

<if(withCaption)>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,23 @@ $ const blockName = "section-feed-content-node";
<if(displayImage)>
<marko-web-element block-name=blockName name="image-wrapper">
<if(primaryImage.src)>
$ const src = buildImgixUrl(primaryImage.src, imageOptions);
$ const srcset = [`${buildImgixUrl(src, { dpr: 2 })} 2x`];
<marko-web-link href=get(content, "siteContext.path") attrs=linkAttrs>
<marko-web-img
src=src
srcset=srcset
alt=primaryImage.alt
$ const src = buildImgixUrl(primaryImage.src, { w: 250, h: 167, fit: "crop" });
$ const srcset = [src, `${buildImgixUrl(src, { dpr: 2 })} 2x`];

$ const srcMobile = buildImgixUrl(primaryImage.src, { w: 112, h: 112, fit: "crop" });
$ const srcsetMobile = [srcMobile, `${buildImgixUrl(srcMobile, { dpr: 2 })} 2x`];

<marko-web-picture>
<@link href=get(content, "siteContext.path") attrs=linkAttrs />
<@source srcset=srcset media="(min-width: 768px)" />
<@image
src=srcMobile
srcset=srcsetMobile
class=[`${blockName}__image`]
alt=primaryImage.alt
lazyload=lazyload
/>
</marko-web-link>
</marko-web-picture>
</if>
</marko-web-element>
</if>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,16 @@ $marko-web-primary-image-margin: 1.5rem !default;
&--aligned {
max-width: $skin-aligned-image-width;
margin-bottom: 0;
img {
max-width: $skin-aligned-image-width;
}

@include media-breakpoint-down(xs) {
max-width: 100%;
margin: $skin-aligned-body-image-spacer auto;
img {
max-width: 100%;
}

#{ $self } {
&__image {
Expand Down
5 changes: 5 additions & 0 deletions packages/marko-web/components/document/index.marko
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ $ const wrapper = getAsObject(input, "bodyWrapper");
</script>
<!-- load lazysizes -->
<script src="/dist/js/lazysizes/v5.3.2.js" async></script>
<!-- load picturefill -->
<script>
document.createElement( "picture" );
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/picturefill/3.0.3/picturefill.min.js" async></script>

<${input.head} />
</head>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { getAsArray } from "@parameter1/base-cms-object-path";
$ const { config } = out.global;
$ const { src, alt } = input;
$ const lazyload = config.lazyloadImages() && input.lazyload !== false
$ const srcset = getAsArray(input.srcset).join(",") || null;
$ const srcset = getAsArray(input.srcset).join(", ") || null;

$ const classNames = [input.class];
$ if (lazyload) classNames.push("lazyload");
Expand Down
35 changes: 35 additions & 0 deletions packages/marko-web/components/element/marko.json
Original file line number Diff line number Diff line change
Expand Up @@ -162,5 +162,40 @@
"@class": "string",
"@attrs": "object",
"@modifiers": "array"
},
"<marko-web-picture>": {
"template": "./picture.marko",
"<image>": {
"@src": "string",
"@srcset": "array",
"@alt": "string",
"@lazyload": {
"type": "boolean",
"default-value": true
},
"@class": "string",
"@attrs": "object",
"@link": "object"
},
"<link>": {
"<before>": {},
"<after>": {},
"@href": "string",
"@target": "string",
"@title": "string",
"@rel": "string",
"@class": "string",
"@attrs": "object"
},
"@sources <source>[]": {
"@media": {
"type": "string",
"required": true
},
"@srcset": {
"type": "array",
"required": true
}
}
}
}
36 changes: 36 additions & 0 deletions packages/marko-web/components/element/picture.marko
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { getAsArray } from "@parameter1/base-cms-object-path";

$ const { link, sources = [], image } = input;

$ const hasImage = Boolean(image.src);

<if(hasImage)>
<if(link)>
<marko-core-link
before=link.before
after=link.after
href=link.href
target=link.target
title=link.title
rel=link.rel
class=link.class
attrs=link.attrs
>
<marko-web-picture image=image sources=sources />
</marko-core-link>
</if>
<else>
<picture>
<for|s| of=sources>
$ const srcset = image.lazyload ? null : s.srcset.join(", ");
$ const dataSrcset = image.lazyload ? s.srcset.join(", ") : null;
<source
srcset=srcset
data-srcset=dataSrcset
media=s.media
>
</for>
<image ...image />
</picture>
</else>
</if>
39 changes: 34 additions & 5 deletions packages/marko-web/utils/embedded-media/image.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const { buildImgixUrl } = require('@parameter1/base-cms-image');

const stringifyAttrs = attrs => Object.keys(attrs).reduce((arr, key) => {
const value = attrs[key];
if (value) arr.push(`${key}="${value}"`);
Expand All @@ -10,23 +12,50 @@ module.exports = (tag, { config } = {}, { lazyloadImages } = {}) => {
const alt = tag.get('alt');
const caption = tag.get('caption');
const credit = tag.get('credit');
const align = tag.get('align');

const width = tag.get('width');
const height = tag.get('height');

const attrs = {
'data-embed-type': tag.type,
'data-embed-id': tag.id,
'data-embed-align': tag.get('align'),
'data-embed-align': align,
};

const minWidth = 400;
const maxWidth = (align) ? minWidth : 700;

const maxSrcset = `${buildImgixUrl(src, { w: maxWidth })}, ${buildImgixUrl(src, { w: maxWidth, dpr: 2 })} 2x`;

const sources = [
{
srcset: lazyload ? null : maxSrcset,
'data-srcset': lazyload ? maxSrcset : null,
media: '(min-width: 576px)',
},
].map(source => `<source ${stringifyAttrs(source)}>`).join('');

const minSrc = buildImgixUrl(src, { w: minWidth });
const minSrcset = `${buildImgixUrl(src, { w: minWidth, dpr: 2 })} 2x`;

const transparentImg = 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
const imgAttrs = {
class: lazyload ? 'lazyload' : null,
src: lazyload ? 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' : src,
'data-src': lazyload ? src : null,
src: lazyload ? transparentImg : minSrc,
srcset: lazyload ? null : minSrcset,
'data-src': lazyload ? minSrc : null,
'data-srcset': lazyload ? minSrcset : null,
'data-image-id': tag.id,
alt,
width: (width && height) ? minWidth : null,
height: (height && height) ? Math.round(height / width * minWidth) : null,
};

const captionElement = caption ? `<span class="caption">${caption}</span>` : '';
const creditElement = credit ? `<span class="credit">${credit}</span>` : '';

const img = `<img ${stringifyAttrs(imgAttrs)}>${captionElement}${creditElement}`;
return `<span ${stringifyAttrs(attrs)}>${img}</span>`;
const img = `<img ${stringifyAttrs(imgAttrs)}>`;
const picture = `<picture>${sources}${img}${captionElement}${creditElement}</picture>`;
return `<span ${stringifyAttrs(attrs)}>${picture}</span>`;
};

0 comments on commit f69a072

Please sign in to comment.