Improvements to media pickers/crop handling and URL generation (#10529)

This commit is contained in:
Ronald Barendse
2021-06-28 09:28:32 +02:00
committed by GitHub
parent 44c814a550
commit 5b9cd1bd87
10 changed files with 407 additions and 120 deletions

View File

@@ -1,15 +1,86 @@
using System;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors.ValueConverters;
namespace Umbraco.Core.Models
{
/// <summary>
/// Model used in Razor Views for rendering
/// Represents a media item with local crops.
/// </summary>
public class MediaWithCrops
/// <seealso cref="Umbraco.Core.Models.PublishedContent.PublishedContentWrapped" />
public class MediaWithCrops : PublishedContentWrapped
{
public IPublishedContent MediaItem { get; set; }
/// <summary>
/// Gets the media item.
/// </summary>
/// <value>
/// The media item.
/// </value>
[Obsolete("This instance now implements IPublishedContent by wrapping the media item, use the extension methods directly on MediaWithCrops or use the Content property to get the media item instead.")]
public IPublishedContent MediaItem => Content;
public ImageCropperValue LocalCrops { get; set; }
/// <summary>
/// Gets the content/media item.
/// </summary>
/// <value>
/// The content/media item.
/// </value>
public IPublishedContent Content => Unwrap();
/// <summary>
/// Gets the local crops.
/// </summary>
/// <value>
/// The local crops.
/// </value>
public ImageCropperValue LocalCrops { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MediaWithCrops" /> class.
/// </summary>
/// <param name="content">The content.</param>
/// <param name="localCrops">The local crops.</param>
public MediaWithCrops(IPublishedContent content, ImageCropperValue localCrops)
: base(content)
{
LocalCrops = localCrops;
}
}
/// <summary>
/// Represents a media item with local crops.
/// </summary>
/// <typeparam name="T">The type of the media item.</typeparam>
/// <seealso cref="Umbraco.Core.Models.PublishedContent.PublishedContentWrapped" />
public class MediaWithCrops<T> : MediaWithCrops
where T : IPublishedContent
{
/// <summary>
/// Gets the media item.
/// </summary>
/// <value>
/// The media item.
/// </value>
public new T Content { get; }
/// <summary>
/// Initializes a new instance of the <see cref="MediaWithCrops{T}" /> class.
/// </summary>
/// <param name="content">The content.</param>
/// <param name="localCrops">The local crops.</param>
public MediaWithCrops(T content, ImageCropperValue localCrops)
: base(content, localCrops)
{
Content = content;
}
/// <summary>
/// Performs an implicit conversion from <see cref="MediaWithCrops{T}" /> to <see cref="T" />.
/// </summary>
/// <param name="mediaWithCrops">The media with crops.</param>
/// <returns>
/// The result of the conversion.
/// </returns>
public static implicit operator T(MediaWithCrops<T> mediaWithCrops) => mediaWithCrops.Content;
}
}

View File

@@ -1,4 +1,8 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core.PropertyEditors.ValueConverters;
using static Umbraco.Core.PropertyEditors.ValueConverters.ImageCropperValue;
namespace Umbraco.Core.PropertyEditors
{
@@ -22,4 +26,35 @@ namespace Umbraco.Core.PropertyEditors
public int Height { get; set; }
}
}
internal static class ImageCropperConfigurationExtensions
{
/// <summary>
/// Applies the configuration to ensure only valid crops are kept and have the correct width/height.
/// </summary>
/// <param name="configuration">The configuration.</param>
public static void ApplyConfiguration(this ImageCropperValue imageCropperValue, ImageCropperConfiguration configuration)
{
var crops = new List<ImageCropperCrop>();
var configuredCrops = configuration?.Crops;
if (configuredCrops != null)
{
foreach (var configuredCrop in configuredCrops)
{
var crop = imageCropperValue.Crops?.FirstOrDefault(x => x.Alias == configuredCrop.Alias);
crops.Add(new ImageCropperCrop
{
Alias = configuredCrop.Alias,
Width = configuredCrop.Width,
Height = configuredCrop.Height,
Coordinates = crop?.Coordinates
});
}
}
imageCropperValue.Crops = crops;
}
}
}

View File

@@ -140,7 +140,7 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
/// Determines whether the value has a specified crop.
/// </summary>
public bool HasCrop(string alias)
=> Crops.Any(x => x.Alias == alias);
=> Crops != null && Crops.Any(x => x.Alias == alias);
/// <summary>
/// Determines whether the value has a source image.
@@ -148,46 +148,35 @@ namespace Umbraco.Core.PropertyEditors.ValueConverters
public bool HasImage()
=> !string.IsNullOrWhiteSpace(Src);
/// <summary>
/// Applies a configuration.
/// </summary>
/// <remarks>Ensures that all crops defined in the configuration exists in the value.</remarks>
internal void ApplyConfiguration(ImageCropperConfiguration configuration)
internal ImageCropperValue Merge(ImageCropperValue imageCropperValue)
{
// merge the crop values - the alias + width + height comes from
// configuration, but each crop can store its own coordinates
var configuredCrops = configuration?.Crops;
if (configuredCrops == null) return;
//Use Crops if it's not null, otherwise create a new list
var crops = Crops?.ToList() ?? new List<ImageCropperCrop>();
foreach (var configuredCrop in configuredCrops)
var incomingCrops = imageCropperValue?.Crops;
if (incomingCrops != null)
{
var crop = crops.FirstOrDefault(x => x.Alias == configuredCrop.Alias);
if (crop != null)
foreach (var incomingCrop in incomingCrops)
{
// found, apply the height & width
crop.Width = configuredCrop.Width;
crop.Height = configuredCrop.Height;
}
else
{
// not found, add
crops.Add(new ImageCropperCrop
var crop = crops.FirstOrDefault(x => x.Alias == incomingCrop.Alias);
if (crop == null)
{
Alias = configuredCrop.Alias,
Width = configuredCrop.Width,
Height = configuredCrop.Height
});
// Add incoming crop
crops.Add(incomingCrop);
}
else if (crop.Coordinates == null)
{
// Use incoming crop coordinates
crop.Coordinates = incomingCrop.Coordinates;
}
}
}
// assume we don't have to remove the crops in value, that
// are not part of configuration anymore?
Crops = crops;
return new ImageCropperValue()
{
Src = !string.IsNullOrWhiteSpace(Src) ? Src : imageCropperValue?.Src,
Crops = crops,
FocalPoint = FocalPoint ?? imageCropperValue?.FocalPoint
};
}
#region IEquatable

View File

@@ -82,8 +82,20 @@ namespace Umbraco.Tests.PropertyEditors
var mediaFileSystem = new MediaFileSystem(Mock.Of<IFileSystem>(), config, scheme, logger);
var imageCropperConfiguration = new ImageCropperConfiguration()
{
Crops = new[]
{
new ImageCropperConfiguration.Crop()
{
Alias = "thumb",
Width = 100,
Height = 100
}
}
};
var dataTypeService = new TestObjects.TestDataTypeService(
new DataType(new ImageCropperPropertyEditor(Mock.Of<ILogger>(), mediaFileSystem, Mock.Of<IContentSection>(), Mock.Of<IDataTypeService>())) { Id = 1 });
new DataType(new ImageCropperPropertyEditor(Mock.Of<ILogger>(), mediaFileSystem, Mock.Of<IContentSection>(), Mock.Of<IDataTypeService>())) { Id = 1, Configuration = imageCropperConfiguration });
var factory = new PublishedContentTypeFactory(Mock.Of<IPublishedModelFactory>(), new PropertyValueConverterCollection(Array.Empty<IPropertyValueConverter>()), dataTypeService);

View File

@@ -28,9 +28,30 @@ namespace Umbraco.Web
return mediaItem.GetCropUrl(imageUrlGenerator, cropAlias: cropAlias, useCropDimensions: true);
}
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string cropAlias, IImageUrlGenerator imageUrlGenerator)
{
return mediaWithCrops.GetCropUrl(imageUrlGenerator, cropAlias: cropAlias, useCropDimensions: true);
}
[Obsolete("Use the GetCropUrl overload with the updated parameter order and note this implementation has changed to get the URL from the media item.")]
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, IImageUrlGenerator imageUrlGenerator, ImageCropperValue imageCropperValue)
{
return mediaItem.Url().GetCropUrl(imageUrlGenerator, imageCropperValue, cropAlias: cropAlias, useCropDimensions: true);
return mediaItem.GetCropUrl(imageCropperValue, cropAlias, imageUrlGenerator);
}
/// <summary>
/// Gets the crop URL by using only the specified <paramref name="imageCropperValue" />.
/// </summary>
/// <param name="mediaItem">The media item.</param>
/// <param name="imageCropperValue">The image cropper value.</param>
/// <param name="cropAlias">The crop alias.</param>
/// <param name="imageUrlGenerator">The image URL generator.</param>
/// <returns>
/// The image crop URL.
/// </returns>
public static string GetCropUrl(this IPublishedContent mediaItem, ImageCropperValue imageCropperValue, string cropAlias, IImageUrlGenerator imageUrlGenerator)
{
return mediaItem.GetCropUrl(imageUrlGenerator, imageCropperValue, true, cropAlias: cropAlias, useCropDimensions: true);
}
/// <summary>
@@ -53,6 +74,11 @@ namespace Umbraco.Web
return mediaItem.GetCropUrl(imageUrlGenerator, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
}
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string propertyAlias, string cropAlias, IImageUrlGenerator imageUrlGenerator)
{
return mediaWithCrops.GetCropUrl(imageUrlGenerator, propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
}
/// <summary>
/// Gets the ImageProcessor URL from the IPublishedContent item.
/// </summary>
@@ -123,7 +149,51 @@ namespace Umbraco.Web
ImageCropRatioMode? ratioMode = null,
bool upScale = true)
{
if (mediaItem == null) throw new ArgumentNullException("mediaItem");
return mediaItem.GetCropUrl(imageUrlGenerator, null, false, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
}
public static string GetCropUrl(
this MediaWithCrops mediaWithCrops,
IImageUrlGenerator imageUrlGenerator,
int? width = null,
int? height = null,
string propertyAlias = Constants.Conventions.Media.File,
string cropAlias = null,
int? quality = null,
ImageCropMode? imageCropMode = null,
ImageCropAnchor? imageCropAnchor = null,
bool preferFocalPoint = false,
bool useCropDimensions = false,
bool cacheBuster = true,
string furtherOptions = null,
ImageCropRatioMode? ratioMode = null,
bool upScale = true)
{
if (mediaWithCrops == null) throw new ArgumentNullException(nameof(mediaWithCrops));
return mediaWithCrops.Content.GetCropUrl(imageUrlGenerator, mediaWithCrops.LocalCrops, false, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
}
private static string GetCropUrl(
this IPublishedContent mediaItem,
IImageUrlGenerator imageUrlGenerator,
ImageCropperValue localCrops,
bool localCropsOnly,
int? width = null,
int? height = null,
string propertyAlias = Constants.Conventions.Media.File,
string cropAlias = null,
int? quality = null,
ImageCropMode? imageCropMode = null,
ImageCropAnchor? imageCropAnchor = null,
bool preferFocalPoint = false,
bool useCropDimensions = false,
bool cacheBuster = true,
string furtherOptions = null,
ImageCropRatioMode? ratioMode = null,
bool upScale = true)
{
if (mediaItem == null) throw new ArgumentNullException(nameof(mediaItem));
var cacheBusterValue = cacheBuster ? mediaItem.UpdateDate.ToFileTimeUtc().ToString(CultureInfo.InvariantCulture) : null;
@@ -132,31 +202,38 @@ namespace Umbraco.Web
var mediaItemUrl = mediaItem.MediaUrl(propertyAlias: propertyAlias);
//get the default obj from the value converter
var cropperValue = mediaItem.Value(propertyAlias);
//is it strongly typed?
var stronglyTyped = cropperValue as ImageCropperValue;
if (stronglyTyped != null)
// Only get crops from media when required and used
if (localCropsOnly == false && (imageCropMode == ImageCropMode.Crop || imageCropMode == null))
{
return GetCropUrl(
mediaItemUrl, imageUrlGenerator, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
cacheBusterValue, furtherOptions, ratioMode, upScale);
// Get the default cropper value from the value converter
var cropperValue = mediaItem.Value(propertyAlias);
var mediaCrops = cropperValue as ImageCropperValue;
if (mediaCrops == null && cropperValue is JObject jobj)
{
mediaCrops = jobj.ToObject<ImageCropperValue>();
}
if (mediaCrops == null && cropperValue is string imageCropperValue &&
string.IsNullOrEmpty(imageCropperValue) == false && imageCropperValue.DetectIsJson())
{
mediaCrops = imageCropperValue.DeserializeImageCropperValue();
}
// Merge crops
if (localCrops == null)
{
localCrops = mediaCrops;
}
else if (mediaCrops != null)
{
localCrops = localCrops.Merge(mediaCrops);
}
}
//this shouldn't be the case but we'll check
var jobj = cropperValue as JObject;
if (jobj != null)
{
stronglyTyped = jobj.ToObject<ImageCropperValue>();
return GetCropUrl(
mediaItemUrl, imageUrlGenerator, stronglyTyped, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
cacheBusterValue, furtherOptions, ratioMode, upScale);
}
//it's a single string
return GetCropUrl(
mediaItemUrl, imageUrlGenerator, width, height, mediaItemUrl, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
mediaItemUrl, imageUrlGenerator, localCrops, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions,
cacheBusterValue, furtherOptions, ratioMode, upScale);
}
@@ -237,6 +314,7 @@ namespace Umbraco.Web
{
cropDataSet = imageCropperValue.DeserializeImageCropperValue();
}
return GetCropUrl(
imageUrl, imageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode,
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
@@ -381,10 +459,10 @@ namespace Umbraco.Web
return imageUrlGenerator.GetImageUrl(options);
}
[Obsolete("Use GetCrop to merge local and media crops, get automatic cache buster value and have more parameters.")]
public static string GetLocalCropUrl(this MediaWithCrops mediaWithCrops, string alias, IImageUrlGenerator imageUrlGenerator, string cacheBusterValue)
{
return mediaWithCrops.LocalCrops.Src + mediaWithCrops.LocalCrops.GetCropUrl(alias, imageUrlGenerator, cacheBusterValue: cacheBusterValue);
}
}
}

View File

@@ -30,7 +30,21 @@ namespace Umbraco.Web
/// </returns>
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, cropAlias, Current.ImageUrlGenerator);
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, ImageCropperValue imageCropperValue) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, cropAlias, Current.ImageUrlGenerator, imageCropperValue);
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string cropAlias) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, cropAlias, Current.ImageUrlGenerator);
[Obsolete("Use the GetCropUrl overload with the updated parameter order and note this implementation has changed to get the URL from the media item.")]
public static string GetCropUrl(this IPublishedContent mediaItem, string cropAlias, ImageCropperValue imageCropperValue) => mediaItem.GetCropUrl(imageCropperValue, cropAlias);
/// <summary>
/// Gets the crop URL by using only the specified <paramref name="imageCropperValue" />.
/// </summary>
/// <param name="mediaItem">The media item.</param>
/// <param name="imageCropperValue">The image cropper value.</param>
/// <param name="cropAlias">The crop alias.</param>
/// <returns>
/// The image crop URL.
/// </returns>
public static string GetCropUrl(this IPublishedContent mediaItem, ImageCropperValue imageCropperValue, string cropAlias) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, imageCropperValue, cropAlias, Current.ImageUrlGenerator);
/// <summary>
/// Gets the ImageProcessor URL by the crop alias using the specified property containing the image cropper Json data on the IPublishedContent item.
@@ -49,6 +63,8 @@ namespace Umbraco.Web
/// </returns>
public static string GetCropUrl(this IPublishedContent mediaItem, string propertyAlias, string cropAlias) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, propertyAlias, cropAlias, Current.ImageUrlGenerator);
public static string GetCropUrl(this MediaWithCrops mediaWithCrops, string propertyAlias, string cropAlias) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, propertyAlias, cropAlias, Current.ImageUrlGenerator);
/// <summary>
/// Gets the ImageProcessor URL from the IPublishedContent item.
/// </summary>
@@ -118,12 +134,21 @@ namespace Umbraco.Web
ImageCropRatioMode? ratioMode = null,
bool upScale = true) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaItem, Current.ImageUrlGenerator, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
public static string GetLocalCropUrl(this MediaWithCrops mediaWithCrops,
string alias,
string cacheBusterValue = null)
=> ImageCropperTemplateCoreExtensions.GetLocalCropUrl(mediaWithCrops, alias, Current.ImageUrlGenerator, cacheBusterValue);
public static string GetCropUrl(
this MediaWithCrops mediaWithCrops,
int? width = null,
int? height = null,
string propertyAlias = Constants.Conventions.Media.File,
string cropAlias = null,
int? quality = null,
ImageCropMode? imageCropMode = null,
ImageCropAnchor? imageCropAnchor = null,
bool preferFocalPoint = false,
bool useCropDimensions = false,
bool cacheBuster = true,
string furtherOptions = null,
ImageCropRatioMode? ratioMode = null,
bool upScale = true) => ImageCropperTemplateCoreExtensions.GetCropUrl(mediaWithCrops, Current.ImageUrlGenerator, width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
/// <summary>
/// Gets the ImageProcessor URL from the image path.
@@ -261,6 +286,12 @@ namespace Umbraco.Web
ImageCropRatioMode? ratioMode = null,
bool upScale = true) => ImageCropperTemplateCoreExtensions.GetCropUrl(imageUrl, Current.ImageUrlGenerator, cropDataSet, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
[Obsolete("Use GetCrop to merge local and media crops, get automatic cache buster value and have more parameters.")]
public static string GetLocalCropUrl(this MediaWithCrops mediaWithCrops,
string alias,
string cacheBusterValue = null)
=> ImageCropperTemplateCoreExtensions.GetLocalCropUrl(mediaWithCrops, alias, Current.ImageUrlGenerator, cacheBusterValue);
private static readonly JsonSerializerSettings ImageCropperValueJsonSerializerSettings = new JsonSerializerSettings
{
Culture = CultureInfo.InvariantCulture,

View File

@@ -1,6 +1,10 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.ValueConverters;
using static Umbraco.Core.PropertyEditors.ValueConverters.ImageCropperValue;
namespace Umbraco.Web.PropertyEditors
{
@@ -57,4 +61,40 @@ namespace Umbraco.Web.PropertyEditors
public int Height { get; set; }
}
}
internal static class MediaPicker3ConfigurationExtensions
{
/// <summary>
/// Applies the configuration to ensure only valid crops are kept and have the correct width/height.
/// </summary>
/// <param name="configuration">The configuration.</param>
public static void ApplyConfiguration(this ImageCropperValue imageCropperValue, MediaPicker3Configuration configuration)
{
var crops = new List<ImageCropperCrop>();
var configuredCrops = configuration?.Crops;
if (configuredCrops != null)
{
foreach (var configuredCrop in configuredCrops)
{
var crop = imageCropperValue.Crops?.FirstOrDefault(x => x.Alias == configuredCrop.Alias);
crops.Add(new ImageCropperCrop
{
Alias = configuredCrop.Alias,
Width = configuredCrop.Width,
Height = configuredCrop.Height,
Coordinates = crop?.Coordinates
});
}
}
imageCropperValue.Crops = crops;
if (configuration?.EnableLocalFocalPoint == false)
{
imageCropperValue.FocalPoint = null;
}
}
}
}

View File

@@ -120,6 +120,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
settingsData = null;
}
// TODO: This should be optimized/cached, as calling Activator.CreateInstance is slow
var layoutType = typeof(BlockListItem<,>).MakeGenericType(contentData.GetType(), settingsData?.GetType() ?? typeof(IPublishedElement));
var layoutRef = (BlockListItem)Activator.CreateInstance(layoutType, contentGuidUdi, contentData, settingGuidUdi, settingsData);

View File

@@ -51,22 +51,27 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters
var mediaItems = new List<MediaWithCrops>();
var dtos = MediaPicker3PropertyEditor.MediaPicker3PropertyValueEditor.Deserialize(inter);
var configuration = propertyType.DataType.ConfigurationAs<MediaPicker3Configuration>();
foreach (var dto in dtos)
{
var mediaItem = _publishedSnapshotAccessor.PublishedSnapshot.Media.GetById(preview, dto.MediaKey);
if (mediaItem != null)
{
mediaItems.Add(new MediaWithCrops
var localCrops = new ImageCropperValue
{
MediaItem = mediaItem,
LocalCrops = new ImageCropperValue
{
Crops = dto.Crops,
FocalPoint = dto.FocalPoint,
Src = mediaItem.Url()
}
});
Crops = dto.Crops,
FocalPoint = dto.FocalPoint,
Src = mediaItem.Url()
};
localCrops.ApplyConfiguration(configuration);
// TODO: This should be optimized/cached, as calling Activator.CreateInstance is slow
var mediaWithCropsType = typeof(MediaWithCrops<>).MakeGenericType(mediaItem.GetType());
var mediaWithCrops = (MediaWithCrops)Activator.CreateInstance(mediaWithCropsType, mediaItem, localCrops);
mediaItems.Add(mediaWithCrops);
if (!isMultiple)
{

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Web;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors.ValueConverters;
using Umbraco.Web.Composing;
@@ -17,9 +18,10 @@ namespace Umbraco.Web
/// </summary>
public static class UrlHelperRenderExtensions
{
private static readonly IHtmlString EmptyHtmlString = new HtmlString(string.Empty);
private static IHtmlString CreateHtmlString(string value, bool htmlEncode) => htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(value)) : new HtmlString(value);
#region GetCropUrl
/// <summary>
@@ -42,7 +44,17 @@ namespace Umbraco.Web
if (mediaItem == null) return EmptyHtmlString;
var url = mediaItem.GetCropUrl(cropAlias: cropAlias, useCropDimensions: true);
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
return CreateHtmlString(url, htmlEncode);
}
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, MediaWithCrops mediaWithCrops, string cropAlias, bool htmlEncode = true)
{
if (mediaWithCrops == null) return EmptyHtmlString;
var url = mediaWithCrops.GetCropUrl(cropAlias: cropAlias, useCropDimensions: true);
return CreateHtmlString(url, htmlEncode);
}
/// <summary>
@@ -70,7 +82,17 @@ namespace Umbraco.Web
if (mediaItem == null) return EmptyHtmlString;
var url = mediaItem.GetCropUrl(propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
return CreateHtmlString(url, htmlEncode);
}
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, MediaWithCrops mediaWithCrops, string propertyAlias, string cropAlias, bool htmlEncode = true)
{
if (mediaWithCrops == null) return EmptyHtmlString;
var url = mediaWithCrops.GetCropUrl(propertyAlias: propertyAlias, cropAlias: cropAlias, useCropDimensions: true);
return CreateHtmlString(url, htmlEncode);
}
/// <summary>
@@ -150,10 +172,33 @@ namespace Umbraco.Web
{
if (mediaItem == null) return EmptyHtmlString;
var url = mediaItem.GetCropUrl(width, height, propertyAlias, cropAlias, quality, imageCropMode,
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode,
upScale);
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
var url = mediaItem.GetCropUrl(width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
return CreateHtmlString(url, htmlEncode);
}
public static IHtmlString GetCropUrl(this UrlHelper urlHelper,
MediaWithCrops mediaWithCrops,
int? width = null,
int? height = null,
string propertyAlias = Umbraco.Core.Constants.Conventions.Media.File,
string cropAlias = null,
int? quality = null,
ImageCropMode? imageCropMode = null,
ImageCropAnchor? imageCropAnchor = null,
bool preferFocalPoint = false,
bool useCropDimensions = false,
bool cacheBuster = true,
string furtherOptions = null,
ImageCropRatioMode? ratioMode = null,
bool upScale = true,
bool htmlEncode = true)
{
if (mediaWithCrops == null) return EmptyHtmlString;
var url = mediaWithCrops.GetCropUrl(width, height, propertyAlias, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBuster, furtherOptions, ratioMode, upScale);
return CreateHtmlString(url, htmlEncode);
}
/// <summary>
@@ -231,10 +276,18 @@ namespace Umbraco.Web
bool upScale = true,
bool htmlEncode = true)
{
var url = imageUrl.GetCropUrl(width, height, imageCropperValue, cropAlias, quality, imageCropMode,
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode,
upScale);
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
var url = imageUrl.GetCropUrl(width, height, imageCropperValue, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
return CreateHtmlString(url, htmlEncode);
}
public static IHtmlString GetCropUrl(this UrlHelper urlHelper, ImageCropperValue imageCropperValue, string cropAlias, bool htmlEncode = true)
{
if (imageCropperValue == null || string.IsNullOrEmpty(imageCropperValue.Src)) return EmptyHtmlString;
var url = imageCropperValue.Src.GetCropUrl(imageCropperValue, cropAlias: cropAlias, useCropDimensions: true);
return CreateHtmlString(url, htmlEncode);
}
public static IHtmlString GetCropUrl(this UrlHelper urlHelper,
@@ -253,41 +306,13 @@ namespace Umbraco.Web
bool upScale = true,
bool htmlEncode = true)
{
if (imageCropperValue == null) return EmptyHtmlString;
if (imageCropperValue == null || string.IsNullOrEmpty(imageCropperValue.Src)) return EmptyHtmlString;
var imageUrl = imageCropperValue.Src;
var url = imageUrl.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode,
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode,
upScale);
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
var url = imageCropperValue.Src.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode, imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode, upScale);
return CreateHtmlString(url, htmlEncode);
}
public static IHtmlString GetCropUrl(this UrlHelper urlHelper,
ImageCropperValue imageCropperValue,
string cropAlias,
int? width = null,
int? height = null,
int? quality = null,
ImageCropMode? imageCropMode = null,
ImageCropAnchor? imageCropAnchor = null,
bool preferFocalPoint = false,
bool useCropDimensions = true,
string cacheBusterValue = null,
string furtherOptions = null,
ImageCropRatioMode? ratioMode = null,
bool upScale = true,
bool htmlEncode = true)
{
if (imageCropperValue == null) return EmptyHtmlString;
var imageUrl = imageCropperValue.Src;
var url = imageUrl.GetCropUrl(imageCropperValue, width, height, cropAlias, quality, imageCropMode,
imageCropAnchor, preferFocalPoint, useCropDimensions, cacheBusterValue, furtherOptions, ratioMode,
upScale);
return htmlEncode ? new HtmlString(HttpUtility.HtmlEncode(url)) : new HtmlString(url);
}
#endregion
/// <summary>