diff --git a/PictureRenderer/Picture.cs b/PictureRenderer/Picture.cs index 54677be..818663f 100644 --- a/PictureRenderer/Picture.cs +++ b/PictureRenderer/Picture.cs @@ -48,23 +48,19 @@ public static string Render(string[] imagePaths, PictureProfileBase profile, str return Render(imagePaths, profile, altText, LazyLoading.Browser, focalPoints: default, cssClass: cssClass); } - public static string Render(string imagePath, PictureProfileBase profile, string altText = "", LazyLoading lazyLoading = LazyLoading.Browser, (double x, double y) focalPoint = default, string cssClass = "") + public static string Render(string imagePath, PictureProfileBase profile, string altText = "", LazyLoading lazyLoading = LazyLoading.Browser, (double x, double y) focalPoint = default, string cssClass = "", string imgWidth = "") { var pictureData = PictureUtils.GetPictureData(imagePath, profile, altText, focalPoint, cssClass); var sourceElement = RenderSourceElement(pictureData); - - - - var sourceElementWebp = string.Empty; if (!string.IsNullOrEmpty(pictureData.SrcSetWebp)) { sourceElementWebp = RenderSourceElement(pictureData, ImageFormat.Webp); } - var imgElement = RenderImgElement(pictureData, profile, lazyLoading); + var imgElement = RenderImgElement(pictureData, profile, lazyLoading, imgWidth); //Webp source element must be rendered first. Browser selects the first version it supports. return $"{sourceElementWebp}{sourceElement}{imgElement}"; @@ -82,9 +78,9 @@ public static string Render(string[] imagePaths, PictureProfileBase profile, str return $"{sourceElements}{imgElement}"; } - private static string RenderImgElement(PictureData pictureData, PictureProfileBase profile, LazyLoading lazyLoading) + private static string RenderImgElement(PictureData pictureData, PictureProfileBase profile, LazyLoading lazyLoading, string imgWidth = "") { - var widthAndHeightAttributes = profile.ImgWidthHeight ? $"width=\"{profile.FallbackWidth}\"height=\"{Math.Round(profile.FallbackWidth / profile.AspectRatio)}\"" : string.Empty; + var widthAndHeightAttributes = GetImgWidthAndHeightAttributes(profile, imgWidth); var loadingAttribute = lazyLoading == LazyLoading.Browser ? "loading=\"lazy\"" : string.Empty; var classAttribute = string.IsNullOrEmpty(pictureData.CssClass) ? string.Empty : $"class=\"{HttpUtility.HtmlEncode(pictureData.CssClass)}\""; var decodingAttribute = profile.ImageDecoding == ImageDecoding.None ? string.Empty : $"decoding=\"{Enum.GetName(typeof(ImageDecoding), profile.ImageDecoding)?.ToLower()}\""; @@ -92,6 +88,16 @@ private static string RenderImgElement(PictureData pictureData, PictureProfileBa return $"\"{HttpUtility.HtmlEncode(pictureData.AltText)}\"src=\"{pictureData.ImgSrc}\"{widthAndHeightAttributes}{loadingAttribute}{decodingAttribute}{classAttribute}/"; } + private static string GetImgWidthAndHeightAttributes(PictureProfileBase profile, string imgWidth) + { + if (!string.IsNullOrEmpty(imgWidth)) + { + return $"width=\"{imgWidth}\""; + } + + return profile.ImgWidthHeight ? $"width=\"{profile.FallbackWidth}\"height=\"{Math.Round(profile.FallbackWidth / profile.AspectRatio)}\"" : string.Empty; + } + private static string RenderSourceElement(PictureData pictureData, string format = "") { var srcSet = pictureData.SrcSet; diff --git a/PictureRenderer/PictureRenderer.csproj b/PictureRenderer/PictureRenderer.csproj index fe7ae86..9827267 100644 --- a/PictureRenderer/PictureRenderer.csproj +++ b/PictureRenderer/PictureRenderer.csproj @@ -2,7 +2,7 @@ netstandard2.0 - 3.2.0 + 3.3.0 Erik Henningson diff --git a/PictureRendererTests/PictureTests.cs b/PictureRendererTests/PictureTests.cs index 98f85a2..f66ff0d 100644 --- a/PictureRendererTests/PictureTests.cs +++ b/PictureRendererTests/PictureTests.cs @@ -12,7 +12,6 @@ public class PictureTests public void RenderWithoutWebpTest() { const string expected = "\"\"src=\"/myImage.jpg?width=1500&height=844&quality=80\"loading=\"lazy\"decoding=\"async\"/"; - var profile = new ImageSharpProfile() { SrcSetWidths = new[] { 375, 750, 980, 1500 }, @@ -30,9 +29,7 @@ public void RenderWithoutWebpTest() public void RenderWithWebpTest() { const string expected = "\"alt"; - //const string expected = "\"alt"; - - var profile = GetMultiImageProfile(); + var profile = GetTestImageProfile(); var result = PictureRenderer.Picture.Render("/myImage.jpg", profile, "alt text"); @@ -51,7 +48,6 @@ public void RenderWithCssClassAndImageDecodingAuto() ImageDecoding = ImageDecoding.Auto, }; - var result = PictureRenderer.Picture.Render("/myImage.jpg", profile, "alt text", "my-css-class"); Assert.Equal(expected, result); @@ -61,7 +57,6 @@ public void RenderWithCssClassAndImageDecodingAuto() public void RenderWithWidthAndHeightAndNoDecoding() { const string expected = "\"alt"; - var profile = new ImageSharpProfile() { SrcSetWidths = new[] { 150, 300 }, @@ -71,7 +66,6 @@ public void RenderWithWidthAndHeightAndNoDecoding() ImageDecoding = ImageDecoding.None, }; - var result = PictureRenderer.Picture.Render("/myImage.jpg", profile, "alt text"); Assert.Equal(expected, result); @@ -81,7 +75,7 @@ public void RenderWithWidthAndHeightAndNoDecoding() public void RenderMultiImageTest() { const string expected = "\"\"src=\"/myImage.jpg?width=400&height=400&quality=80\"loading=\"lazy\"decoding=\"async\"/"; - var result = Picture.Render(new []{"/myImage.jpg", "/myImage2.png", "/myImage3.jpg" }, GetMultiImageProfile()); + var result = Picture.Render(new []{"/myImage.jpg", "/myImage2.png", "/myImage3.jpg" }, GetTestImageProfile()); Assert.Equal(expected, result); } @@ -90,7 +84,7 @@ public void RenderMultiImageTest() public void RenderMultiImageMissingImageTest() { const string expected = "\"alt"; - var result = Picture.Render(new[] { "/myImage.jpg", "/myImage2.jpg" }, GetMultiImageProfile(), "alt text"); + var result = Picture.Render(new[] { "/myImage.jpg", "/myImage2.jpg" }, GetTestImageProfile(), "alt text"); Assert.Equal(expected, result); } @@ -100,7 +94,7 @@ public void RenderMultiImageWithFocalPointsTest() { const string expected = "\"\"src=\"/myImage.jpg?width=400&height=400&rxy=0.1%2c0.1&quality=80\"loading=\"lazy\"decoding=\"async\"/"; - var result = Picture.Render(new[] { "/myImage.jpg", "/myImage2.png", "/myImage3.jpg" }, GetMultiImageProfile(), focalPoints: new [] { (0.1, 0.1), (0.2, 0.2), (0.3, 0.3) }); + var result = Picture.Render(new[] { "/myImage.jpg", "/myImage2.png", "/myImage3.jpg" }, GetTestImageProfile(), focalPoints: new [] { (0.1, 0.1), (0.2, 0.2), (0.3, 0.3) }); Assert.Equal(expected, result); } @@ -110,12 +104,23 @@ public void RenderMultiImageWithEmptyFocalPointsTest() { const string expected = "\"\"src=\"/myImage.jpg?width=400&height=400&rxy=0.1%2c0.1&quality=80\"loading=\"lazy\"decoding=\"async\"/"; - var result = Picture.Render(new[] { "/myImage.jpg", "/myImage2.png", "/myImage3.jpg" }, GetMultiImageProfile(), focalPoints: new[] { (0.1, 0.1), default, (0.3, 0.3) }); + var result = Picture.Render(new[] { "/myImage.jpg", "/myImage2.png", "/myImage3.jpg" }, GetTestImageProfile(), focalPoints: new[] { (0.1, 0.1), default, (0.3, 0.3) }); + + Assert.Equal(expected, result); + } + + [Fact()] + public void RenderWithImgWidthTest() + { + const string expected = "\"alt"; + var profile = GetTestImageProfile(); + + var result = PictureRenderer.Picture.Render("/myImage.jpg", profile, "alt text", LazyLoading.Browser, default, "", "50%"); Assert.Equal(expected, result); } - private static ImageSharpProfile GetMultiImageProfile() + private static ImageSharpProfile GetTestImageProfile() { //use this to test with both single and multiple images return new ImageSharpProfile() diff --git a/README.md b/README.md index fb8ab03..a8e3206 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,7 @@ See also [sample projects](https://github.com/ErikHen/PictureRenderer.Samples).

## Version history +* **3.3** Adding possibility to set width attribute on img element. Needed for rare edge case in Optimizely CMS. * **3.2** Changing some things reported as warnings by Sonarcloud. * **3.1** Making PictureRenderer.ImageFormat public. Don't understand why it was internal in the first place 😊.