Skip to content

Commit f4280ff

Browse files
ZeegaaniOvergaardnikolajlauridsenelit0451
authored
V11: merge v10 to v11 (#13200)
* Fix for potential race condition in packages search (#13153) * search on input allowing to wait for copy/paste etc * invoke resourcePromise() with correct parameters * return the xhrStatus allowing the caller to check if the request was aborted * fix: send in canceler.promise to allow the timeout to work * catch any errors and ignore aborts if they happen * move the logic to handle cancellations outside Angulars $scope.$apply * remove file accidentally committed * V10: Fix request accessor memory leak (#13152) * Dispose OnChange event registration when disposing the notification handler * Ensure that the ApplicationUrl is only initialized once Since notifications handlers are transient,_hasAppUrl and _isInit defaults to false on every request causing it to always be called. * Make notification handler and EnsureApplicationUrl internal * Add missing ForceLeft and ForceRight (#13190) * Fix tags with CSV storage type (#13188) * Fixing null check as default(NRT) is null => default(configuration?.Delimiter) is also null and we were counting on it being the same as default(char) * Adding tests to check cases with multiple tags (or tag made of comma separated values) * Add data-element to umb property so we can find it (#13199) Co-authored-by: Zeegaan <[email protected]> Co-authored-by: Jacob Overgaard <[email protected]> Co-authored-by: Mole <[email protected]> Co-authored-by: Elitsa Marinovska <[email protected]> Co-authored-by: Zeegaan <[email protected]>
1 parent 442342e commit f4280ff

File tree

14 files changed

+172
-33
lines changed

14 files changed

+172
-33
lines changed

src/Umbraco.Core/Models/PropertyTagsExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static class PropertyTagsExtensions
3333
: dataTypeService.GetDataType(property.PropertyType.DataTypeId)?.Configuration;
3434
TagConfiguration? configuration = ConfigurationEditor.ConfigurationAs<TagConfiguration>(configurationObject);
3535

36-
if (configuration?.Delimiter == default && configuration?.Delimiter is not null)
36+
if (configuration is not null && configuration.Delimiter == default)
3737
{
3838
configuration.Delimiter = tagAttribute.Delimiter;
3939
}

src/Umbraco.Infrastructure/Models/Blocks/BlockGridLayoutItem.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ public class BlockGridLayoutItem : IBlockLayoutItem
2525
[JsonProperty("rowSpan", NullValueHandling = NullValueHandling.Ignore)]
2626
public int? RowSpan { get; set; }
2727

28+
[JsonProperty("forceLeft")]
29+
public bool ForceLeft { get; set; }
30+
31+
[JsonProperty("forceRight")]
32+
public bool ForceRight { get; set; }
33+
2834
[JsonProperty("areas", NullValueHandling = NullValueHandling.Ignore)]
2935
public BlockGridLayoutAreaItem[] Areas { get; set; } = Array.Empty<BlockGridLayoutAreaItem>();
3036
}

src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockGridPropertyValueConverter.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ public override bool IsConverter(IPublishedPropertyType propertyType)
4949

5050
blockItem.RowSpan = layoutItem.RowSpan!.Value;
5151
blockItem.ColumnSpan = layoutItem.ColumnSpan!.Value;
52+
blockItem.ForceLeft = layoutItem.ForceLeft;
53+
blockItem.ForceRight = layoutItem.ForceRight;
5254
blockItem.AreaGridColumns = blockConfig.AreaGridColumns;
5355
blockItem.GridColumns = configuration.GridColumns;
5456
blockItem.Areas = layoutItem.Areas.Select(area =>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using Umbraco.Cms.Core.Events;
2+
using Umbraco.Cms.Core.Notifications;
3+
using Umbraco.Cms.Core.Web;
4+
5+
namespace Umbraco.Cms.Web.Common.AspNetCore;
6+
7+
/// <summary>
8+
/// Notification handler which will listen to the <see cref="UmbracoRequestBeginNotification"/>, and ensure that
9+
/// the applicationUrl is set on the first request.
10+
/// </summary>
11+
internal class ApplicationUrlRequestBeginNotificationHandler : INotificationHandler<UmbracoRequestBeginNotification>
12+
{
13+
private readonly IRequestAccessor _requestAccessor;
14+
15+
public ApplicationUrlRequestBeginNotificationHandler(IRequestAccessor requestAccessor) =>
16+
_requestAccessor = requestAccessor;
17+
18+
public void Handle(UmbracoRequestBeginNotification notification)
19+
{
20+
// If someone has replaced the AspNetCoreRequestAccessor we'll do nothing and assume they handle it themselves.
21+
if (_requestAccessor is AspNetCoreRequestAccessor accessor)
22+
{
23+
accessor.EnsureApplicationUrl();
24+
}
25+
}
26+
}

src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace Umbraco.Cms.Web.Common.AspNetCore;
1111

12-
public class AspNetCoreRequestAccessor : IRequestAccessor, INotificationHandler<UmbracoRequestBeginNotification>
12+
public class AspNetCoreRequestAccessor : IRequestAccessor, INotificationHandler<UmbracoRequestBeginNotification>, IDisposable
1313
{
1414
private readonly ISet<string> _applicationUrls = new HashSet<string>();
1515
private readonly IHttpContextAccessor _httpContextAccessor;
@@ -18,6 +18,7 @@ public class AspNetCoreRequestAccessor : IRequestAccessor, INotificationHandler<
1818
private object _initLocker = new();
1919
private bool _isInit;
2020
private WebRoutingSettings _webRoutingSettings;
21+
private readonly IDisposable? _onChangeDisposable;
2122

2223
/// <summary>
2324
/// Initializes a new instance of the <see cref="AspNetCoreRequestAccessor" /> class.
@@ -28,20 +29,19 @@ public AspNetCoreRequestAccessor(
2829
{
2930
_httpContextAccessor = httpContextAccessor;
3031
_webRoutingSettings = webRoutingSettings.CurrentValue;
31-
webRoutingSettings.OnChange(x => _webRoutingSettings = x);
32+
_onChangeDisposable = webRoutingSettings.OnChange(x => _webRoutingSettings = x);
3233
}
3334

3435
/// <summary>
35-
/// This just initializes the application URL on first request attempt
36-
/// TODO: This doesn't belong here, the GetApplicationUrl doesn't belong to IRequestAccessor
37-
/// this should be part of middleware not a lazy init based on an INotification
36+
/// <para>
37+
/// This is now a NoOp, and is no longer used, instead ApplicationUrlRequestBeginNotificationHandler is used
38+
/// </para>
3839
/// </summary>
40+
[Obsolete("This is no longer used, AspNetCoreRequestAccessor will no longer implement INotificationHandler in V12, see ApplicationUrlRequestBeginNotificationHandler instead.")]
3941
public void Handle(UmbracoRequestBeginNotification notification)
40-
=> LazyInitializer.EnsureInitialized(ref _hasAppUrl, ref _isInit, ref _initLocker, () =>
41-
{
42-
GetApplicationUrl();
43-
return true;
44-
});
42+
{
43+
// NoOP
44+
}
4545

4646
/// <inheritdoc />
4747
public string? GetRequestValue(string name) => GetFormValue(name) ?? GetQueryStringValue(name);
@@ -54,6 +54,17 @@ public void Handle(UmbracoRequestBeginNotification notification)
5454
? new Uri(_httpContextAccessor.HttpContext.Request.GetEncodedUrl())
5555
: null;
5656

57+
/// <summary>
58+
/// Ensure that the ApplicationUrl is set on the first request, this is using a LazyInitializer, so the code will only be run the first time
59+
/// </summary>
60+
/// TODO: This doesn't belong here, the GetApplicationUrl doesn't belong to IRequestAccessor
61+
internal void EnsureApplicationUrl() =>
62+
LazyInitializer.EnsureInitialized(ref _hasAppUrl, ref _isInit, ref _initLocker, () =>
63+
{
64+
GetApplicationUrl();
65+
return true;
66+
});
67+
5768
public Uri? GetApplicationUrl()
5869
{
5970
// Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that
@@ -63,7 +74,7 @@ public void Handle(UmbracoRequestBeginNotification notification)
6374
// see U4-10626 - in some cases we want to reset the application url
6475
// (this is a simplified version of what was in 7.x)
6576
// note: should this be optional? is it expensive?
66-
if (!(_webRoutingSettings.UmbracoApplicationUrl is null))
77+
if (_webRoutingSettings.UmbracoApplicationUrl is not null)
6778
{
6879
return new Uri(_webRoutingSettings.UmbracoApplicationUrl);
6980
}
@@ -96,4 +107,6 @@ public void Handle(UmbracoRequestBeginNotification notification)
96107

97108
return request.Form[name];
98109
}
110+
111+
public void Dispose() => _onChangeDisposable?.Dispose();
99112
}

src/Umbraco.Web.Common/DependencyInjection/UmbracoBuilderExtensions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,7 @@ public static IUmbracoBuilder AddWebComponents(this IUmbracoBuilder builder)
297297
// AspNetCore specific services
298298
builder.Services.AddUnique<IRequestAccessor, AspNetCoreRequestAccessor>();
299299
builder.AddNotificationHandler<UmbracoRequestBeginNotification, AspNetCoreRequestAccessor>();
300+
builder.AddNotificationHandler<UmbracoRequestBeginNotification, ApplicationUrlRequestBeginNotificationHandler>();
300301

301302
// Password hasher
302303
builder.Services.AddUnique<IPasswordHasher, AspNetCorePasswordHasher>();

src/Umbraco.Web.UI.Client/src/common/resources/ourpackagerrepository.resource.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ function ourPackageRepositoryResource($q, $http, umbDataFormatter, umbRequestHel
5757
if (canceler) {
5858
httpConfig["timeout"] = canceler;
5959
}
60-
60+
6161
if (category === undefined) {
6262
category = "";
6363
}
@@ -69,8 +69,10 @@ function ourPackageRepositoryResource($q, $http, umbDataFormatter, umbRequestHel
6969
var order = !orderBy ? "&order=Default" : ("&order=" + orderBy);
7070

7171
return umbRequestHelper.resourcePromise(
72-
$http.get(baseurl + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize + "&category=" + category + "&query=" + query + order + "&version=" + Umbraco.Sys.ServerVariables.application.version),
73-
httpConfig,
72+
$http.get(
73+
baseurl + "?pageIndex=" + pageIndex + "&pageSize=" + pageSize + "&category=" + category + "&query=" + query + order + "&version=" + Umbraco.Sys.ServerVariables.application.version,
74+
httpConfig
75+
),
7476
'Failed to query packages');
7577
}
7678

src/Umbraco.Web.UI.Client/src/common/services/umbrequesthelper.service.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,8 @@ function umbRequestHelper($http, $q, notificationsService, eventsService, formHe
197197
return $q.reject({
198198
errorMsg: result.errorMsg,
199199
data: result.data,
200-
status: result.status
200+
status: result.status,
201+
xhrStatus: response.xhrStatus
201202
});
202203
});
203204

src/Umbraco.Web.UI.Client/src/views/components/property/umb-property.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
<div class="control-header" ng-hide="vm.property.hideLabel === true">
1111

12-
<label class="control-label" for="{{vm.property.alias}}" ng-attr-title="{{vm.controlLabelTitle}}">{{vm.property.label}}<span ng-if="vm.property.validation.mandatory || vm.property.ncMandatory"><strong class="umb-control-required">*</strong></span></label>
12+
<label data-element="property-label-{{vm.property.alias}}" class="control-label" for="{{vm.property.alias}}" ng-attr-title="{{vm.controlLabelTitle}}">{{vm.property.label}}<span ng-if="vm.property.validation.mandatory || vm.property.ncMandatory"><strong class="umb-control-required">*</strong></span></label>
1313

1414
<umb-property-actions actions="vm.propertyActions"></umb-property-actions>
1515

@@ -41,11 +41,11 @@
4141
<span ng-if="vm.property.variations === 'Culture' || vm.property.variations === 'CultureAndSegment'" class="umb-property-variant-label">
4242
{{ vm.property.culture }}
4343
</span>
44-
44+
4545
<span ng-if="vm.property.variations === 'Culture' && vm.node.documentType.variations === 'CultureAndSegment'" class="umb-property-variant-label">
4646
<localize key="languages_invariantSegmentProperty"></localize>
4747
</span>
48-
48+
4949
<span ng-if="vm.property.variations === 'Segment' || vm.property.variations === 'CultureAndSegment'" class="umb-property-variant-label">
5050
<span>{{ vm.property.segment }}</span>
5151
<span ng-if="!vm.property.segment">Default</span>

src/Umbraco.Web.UI.Client/src/views/macros/views/settings.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<input type="hidden" name="partialView" ng-model="mandatoryViewValidator" ng-required="!model.macro.node" />
2222

2323
<button type="button"
24+
id="{{vm.macroPartialViewPickerProperty.alias}}"
2425
class="umb-node-preview-add"
2526
ng-show="!model.macro.node"
2627
ng-click="model.openViewPicker()">

0 commit comments

Comments
 (0)