diff --git a/DNN Platform/Dnn.AuthServices.Jwt/Components/Common/Controllers/JwtController.cs b/DNN Platform/Dnn.AuthServices.Jwt/Components/Common/Controllers/JwtController.cs index c1c8766979c..2396b0ca20d 100644 --- a/DNN Platform/Dnn.AuthServices.Jwt/Components/Common/Controllers/JwtController.cs +++ b/DNN Platform/Dnn.AuthServices.Jwt/Components/Common/Controllers/JwtController.cs @@ -304,7 +304,19 @@ private static string CreateJwtToken(byte[] symmetricKey, string issuer, Persist var subject = new ClaimsIdentity(); subject.AddClaim(new Claim(SessionClaimType, persistedToken.TokenId)); - subject.AddClaims(roles.Select(r => new Claim(ClaimTypes.Role, r))); + + // Add roles using both the standard schema URI (ClaimTypes.Role) for standards compliance + // and the legacy "role" claim type for backward compatibility with existing consumers + foreach (var role in roles) + { + subject.AddClaim(new Claim(ClaimTypes.Role, role)); + subject.AddClaim(new Claim("role", role)); + } + + // Add deprecation notice for the legacy "role" claim format + subject.AddClaim(new Claim( + "dnn:deprecation:role", + "The role claim is deprecated. Use http://schemas.microsoft.com/ws/2008/06/identity/claims/role instead. The role claim will be removed in DNN v12.0.0.")); var notBefore = DateTime.UtcNow.AddMinutes(-ClockSkew); var expires = persistedToken.TokenExpiry; diff --git a/DNN Platform/Dnn.AuthServices.Jwt/Components/Entity/LoginResultData.cs b/DNN Platform/Dnn.AuthServices.Jwt/Components/Entity/LoginResultData.cs index f88cb1e0023..9f6656e9816 100644 --- a/DNN Platform/Dnn.AuthServices.Jwt/Components/Entity/LoginResultData.cs +++ b/DNN Platform/Dnn.AuthServices.Jwt/Components/Entity/LoginResultData.cs @@ -29,5 +29,10 @@ public class LoginResultData /// Gets or sets any error message. [JsonIgnore] public string Error { get; set; } + + /// Gets deprecation warnings about the JWT token format (included in all responses). + [JsonProperty("deprecationNotice")] + public string DeprecationNotice => + "The role claim format in JWT tokens is deprecated. Please use http://schemas.microsoft.com/ws/2008/06/identity/claims/role instead. The legacy role claim will be removed in DNN Platform v12.0.0."; } } diff --git a/DNN Platform/DotNetNuke.Web.Client.ResourceManager/Models/ResourceBase.cs b/DNN Platform/DotNetNuke.Web.Client.ResourceManager/Models/ResourceBase.cs index d73c8f9b2b2..4d3807740b0 100644 --- a/DNN Platform/DotNetNuke.Web.Client.ResourceManager/Models/ResourceBase.cs +++ b/DNN Platform/DotNetNuke.Web.Client.ResourceManager/Models/ResourceBase.cs @@ -123,16 +123,18 @@ protected void RenderBlocking(StringBuilder htmlString) /// The HTML string builder to append to. protected void RenderCrossOriginAttribute(StringBuilder htmlString) { - if (this.CrossOrigin != CrossOrigin.None) + switch (this.CrossOrigin) { - if (this.CrossOrigin == CrossOrigin.UseCredentials) - { + case CrossOrigin.UseCredentials: htmlString.Append($" crossorigin=\"use-credentials\""); - } - else - { + return; + case CrossOrigin.Anonymous: htmlString.Append($" crossorigin=\"anonymous\""); - } + return; + case CrossOrigin.None: + return; + default: + throw new InvalidOperationException($"Unexpected CrossOrigin value: {this.CrossOrigin}"); } } @@ -140,16 +142,18 @@ protected void RenderCrossOriginAttribute(StringBuilder htmlString) /// The HTML string builder to append to. protected void RenderFetchPriority(StringBuilder htmlString) { - if (this.FetchPriority != FetchPriority.Auto) + switch (this.FetchPriority) { - if (this.FetchPriority == FetchPriority.High) - { + case FetchPriority.High: htmlString.Append($" fetchpriority=\"high\""); - } - else if (this.FetchPriority == FetchPriority.Low) - { + return; + case FetchPriority.Low: htmlString.Append($" fetchpriority=\"low\""); - } + return; + case FetchPriority.Auto: + return; + default: + throw new InvalidOperationException($"Unexpected FetchPriority value: {this.FetchPriority}"); } } @@ -167,35 +171,36 @@ protected void RenderIntegrity(StringBuilder htmlString) /// The HTML string builder to append to. protected void RenderReferrerPolicy(StringBuilder htmlString) { - if (this.ReferrerPolicy != ReferrerPolicy.None) + switch (this.ReferrerPolicy) { - switch (this.ReferrerPolicy) - { - case ReferrerPolicy.NoReferrer: - htmlString.Append(" referrerpolicy=\"no-referrer\""); - break; - case ReferrerPolicy.NoReferrerWhenDowngrade: - htmlString.Append(" referrerpolicy=\"no-referrer-when-downgrade\""); - break; - case ReferrerPolicy.Origin: - htmlString.Append(" referrerpolicy=\"origin\""); - break; - case ReferrerPolicy.OriginWhenCrossOrigin: - htmlString.Append(" referrerpolicy=\"origin-when-cross-origin\""); - break; - case ReferrerPolicy.SameOrigin: - htmlString.Append(" referrerpolicy=\"same-origin\""); - break; - case ReferrerPolicy.StrictOrigin: - htmlString.Append(" referrerpolicy=\"strict-origin\""); - break; - case ReferrerPolicy.StrictOriginWhenCrossOrigin: - htmlString.Append(" referrerpolicy=\"strict-origin-when-cross-origin\""); - break; - case ReferrerPolicy.UnsafeUrl: - htmlString.Append(" referrerpolicy=\"unsafe-url\""); - break; - } + case ReferrerPolicy.NoReferrer: + htmlString.Append(" referrerpolicy=\"no-referrer\""); + break; + case ReferrerPolicy.NoReferrerWhenDowngrade: + htmlString.Append(" referrerpolicy=\"no-referrer-when-downgrade\""); + break; + case ReferrerPolicy.Origin: + htmlString.Append(" referrerpolicy=\"origin\""); + break; + case ReferrerPolicy.OriginWhenCrossOrigin: + htmlString.Append(" referrerpolicy=\"origin-when-cross-origin\""); + break; + case ReferrerPolicy.SameOrigin: + htmlString.Append(" referrerpolicy=\"same-origin\""); + break; + case ReferrerPolicy.StrictOrigin: + htmlString.Append(" referrerpolicy=\"strict-origin\""); + break; + case ReferrerPolicy.StrictOriginWhenCrossOrigin: + htmlString.Append(" referrerpolicy=\"strict-origin-when-cross-origin\""); + break; + case ReferrerPolicy.UnsafeUrl: + htmlString.Append(" referrerpolicy=\"unsafe-url\""); + break; + case ReferrerPolicy.None: + return; + default: + throw new InvalidOperationException($"Unexpected ReferrerPolicy value: {this.ReferrerPolicy}"); } } diff --git a/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceExclude.cs b/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceExclude.cs index a4bbc788814..e44a629d4ef 100644 --- a/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceExclude.cs +++ b/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceExclude.cs @@ -36,7 +36,7 @@ protected ClientResourceExclude(IClientResourceController clientResourceControll /// public ClientDependencyType DependencyType { get; internal set; } - protected override void OnInit(EventArgs e) + protected override void OnLoad(EventArgs e) { switch (this.DependencyType) { diff --git a/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceInclude.cs b/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceInclude.cs index 33dd38bef64..c6bc71bc476 100644 --- a/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceInclude.cs +++ b/DNN Platform/DotNetNuke.Web.Client/Controls/ClientResourceInclude.cs @@ -4,9 +4,13 @@ namespace DotNetNuke.Web.Client.ClientResourceManagement { + using System; + using System.Collections.Generic; using System.Web.UI; + using DotNetNuke.Abstractions.ClientResources; using DotNetNuke.Web.Client.Cdf; + using DotNetNuke.Web.Client.ResourceManager; /// Represents an included client resource. public abstract class ClientResourceInclude : Control @@ -28,9 +32,6 @@ protected ClientResourceInclude() /// Gets or sets the priority for the client resource. Resources with lower priority values are included before those with higher values. public int Priority { get; set; } - /// Gets or sets the group for the client resource. Resources in the same group are processed together. - public int Group { get; set; } - /// Gets or sets the name of the script (e.g. jQuery, Bootstrap, Angular, etc.). public string Name { get; set; } @@ -48,5 +49,143 @@ protected ClientResourceInclude() /// Gets or sets a value indicating whether to add the HTML tag for this resource to the page output. public bool AddTag { get; set; } + + /// Gets or sets the CDN URL of the resource. + public string CdnUrl { get; set; } + + /// Gets or sets a value indicating whether to render the blocking attribute. + public bool Blocking { get; set; } + + /// Gets or sets the integrity hash of the resource. + public string Integrity { get; set; } + + /// Gets or sets the value of the crossorigin attribute. + public CrossOrigin CrossOrigin { get; set; } + + /// Gets or sets the value of the fetchpriority attribute. + public FetchPriority FetchPriority { get; set; } + + /// Gets or sets the value of the referrerpolicy attribute. + public ReferrerPolicy ReferrerPolicy { get; set; } + + /// Gets additional attributes in the HTML markup for the resource. + public IDictionary HtmlAttributes { get; private set; } = new Dictionary(); + + /// Gets or sets the for this resource via a string which is parsed. + /// The syntax for the string must be: key1:value1,key2:value2 etc. + public string HtmlAttributesAsString { get; set; } + + /// Gets or sets the group for the client resource. Resources in the same group are processed together. + [Obsolete("Deprecated in DotNetNuke 10.2.0. Grouping is no longer supported, there is no replacement within DNN for this functionality. Scheduled removal in v12.0.0.")] + public int Group { get; set; } + + /// Gets or sets a value indicating whether to force this resource to be bundled. No longer supported. + [Obsolete("Deprecated in DotNetNuke 10.2.0. Bundling is no longer supported, there is no replacement within DNN for this functionality. Scheduled removal in v12.0.0.")] + public bool ForceBundle { get; set; } + + /// Sets common properties on the and registers it. + /// The resource to register. + protected void RegisterResource(IResource resource) + { + resource = resource + .SetNameAndVersion(this.Name, this.Version, this.ForceVersion) + .SetProvider(this.ForceProvider) + .SetPriority(this.Priority) + .SetCdnUrl(this.CdnUrl) + .SetIntegrity(this.Integrity) + .SetCrossOrigin(this.CrossOrigin) + .SetFetchPriority(this.FetchPriority) + .SetReferrerPolicy(this.ReferrerPolicy); + if (this.Blocking) + { + resource = resource.SetBlocking(); + } + + var attributes = this.HtmlAttributes; + ParseHtmlAttributesIntoDictionary(this.HtmlAttributesAsString, attributes); + + foreach (var attribute in attributes) + { + resource.AddAttribute(attribute.Key, attribute.Value); + } + + resource.Register(); + } + + /// + private static void ParseHtmlAttributesIntoDictionary(string attributes, IDictionary destination) + { + if (string.IsNullOrEmpty(attributes)) + { + return; + } + + var key = string.Empty; + var val = string.Empty; + var isKey = true; + var isVal = false; + var isValDelimited = false; + for (var i = 0; i < attributes.Length; i++) + { + var c = attributes.ToCharArray()[i]; + if (isKey && c == ':') + { + isKey = false; + isVal = true; + continue; + } + + if (isKey) + { + key += c; + } + + if (!isVal) + { + continue; + } + + if (c == '\'') + { + if (!isValDelimited) + { + isValDelimited = true; + continue; + } + else + { + isValDelimited = false; + if (i == attributes.Length - 1) + { + // if it is the end, add/replace the value + destination[key] = val; + } + + continue; + } + } + + if (c == ',' && !isValDelimited) + { + // we've reached a comma and the value is no longer delimited, this means we create a new key + isKey = true; + isVal = false; + + // now we can add/replace the current value to the dictionary + destination[key] = val; + key = string.Empty; + val = string.Empty; + continue; + } + + val += c; + + if (i == attributes.Length - 1) + { + // if it is the end, add/replace the value + destination[key] = val; + } + } + } } } diff --git a/DNN Platform/DotNetNuke.Web.Client/Controls/DnnCssInclude.cs b/DNN Platform/DotNetNuke.Web.Client/Controls/DnnCssInclude.cs index 7db67e08452..7cc7cf213cc 100644 --- a/DNN Platform/DotNetNuke.Web.Client/Controls/DnnCssInclude.cs +++ b/DNN Platform/DotNetNuke.Web.Client/Controls/DnnCssInclude.cs @@ -2,7 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke.Web.Client.ClientResourceManagement +namespace DotNetNuke.Web.Client.ClientResourceManagement { using System; using System.Web.UI; @@ -11,50 +11,47 @@ namespace DotNetNuke.Web.Client.ClientResourceManagement using DotNetNuke.Web.Client.Cdf; using DotNetNuke.Web.Client.ResourceManager; - /// Registers a CSS resource. - public class DnnCssInclude : ClientResourceInclude + /// Registers a CSS resource. + public class DnnCssInclude : ClientResourceInclude { private readonly IClientResourceController clientResourceController; - /// - /// Initializes a new instance of the class. - /// + /// Initializes a new instance of the class. /// The client resources controller. public DnnCssInclude(IClientResourceController clientResourceController) - : base() - { + { this.clientResourceController = clientResourceController; this.ForceProvider = ClientResourceProviders.DefaultCssProvider; - this.DependencyType = ClientDependencyType.Css; + this.DependencyType = ClientDependencyType.Css; } + /// public string CssMedia { get; set; } + /// + public bool Preload { get; set; } + /// - protected override void OnInit(EventArgs e) + protected override void OnLoad(System.EventArgs e) { - this.clientResourceController.CreateStylesheet(this.FilePath, this.PathNameAlias) - .SetNameAndVersion(this.Name, this.Version, this.ForceVersion) - .SetProvider(this.ForceProvider) - .SetPriority(this.Priority) - .SetMedia(this.CssMedia) - .Register(); + var stylesheet = this.clientResourceController.CreateStylesheet(this.FilePath, this.PathNameAlias) + .SetMedia(this.CssMedia); + if (this.Preload) + { + stylesheet.SetPreload(); + } + + this.RegisterResource(stylesheet); + base.OnLoad(e); } /// - protected override void OnLoad(System.EventArgs e) - { - this.PathNameAlias = string.IsNullOrEmpty(this.PathNameAlias) ? string.Empty : this.PathNameAlias.ToLowerInvariant(); - base.OnLoad(e); + protected override void Render(HtmlTextWriter writer) + { + if (this.AddTag || this.Context.IsDebuggingEnabled) + { + writer.Write("", this.FilePath, this.ForceProvider, this.Priority); + } } - - /// - protected override void Render(HtmlTextWriter writer) - { - if (this.AddTag || this.Context.IsDebuggingEnabled) - { - writer.Write("", this.FilePath, this.ForceProvider, this.Priority); - } - } - } -} + } +} diff --git a/DNN Platform/DotNetNuke.Web.Client/Controls/DnnHtmlInclude.cs b/DNN Platform/DotNetNuke.Web.Client/Controls/DnnHtmlInclude.cs index 1d34c4c10e6..94ae57ec92d 100644 --- a/DNN Platform/DotNetNuke.Web.Client/Controls/DnnHtmlInclude.cs +++ b/DNN Platform/DotNetNuke.Web.Client/Controls/DnnHtmlInclude.cs @@ -47,9 +47,9 @@ public DnnHtmlInclude(IClientResourceController clientResourceController) /// public int Group { get; set; } = 100; - protected override void OnInit(EventArgs e) + protected override void OnLoad(EventArgs e) { - base.OnInit(e); + base.OnLoad(e); this.RegisterIncludes(this.Text); this.Text = string.Empty; } diff --git a/DNN Platform/DotNetNuke.Web.Client/Controls/DnnJsInclude.cs b/DNN Platform/DotNetNuke.Web.Client/Controls/DnnJsInclude.cs index fe227bacf93..80a01f7a295 100644 --- a/DNN Platform/DotNetNuke.Web.Client/Controls/DnnJsInclude.cs +++ b/DNN Platform/DotNetNuke.Web.Client/Controls/DnnJsInclude.cs @@ -2,8 +2,8 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information -namespace DotNetNuke.Web.Client.ClientResourceManagement -{ +namespace DotNetNuke.Web.Client.ClientResourceManagement +{ using System; using System.Web.UI; @@ -11,47 +11,62 @@ namespace DotNetNuke.Web.Client.ClientResourceManagement using DotNetNuke.Web.Client.Cdf; using DotNetNuke.Web.Client.ResourceManager; - /// Registers a JavaScript resource. - public class DnnJsInclude : ClientResourceInclude - { + /// Registers a JavaScript resource. + public class DnnJsInclude : ClientResourceInclude + { private readonly IClientResourceController clientResourceController; - /// - /// Initializes a new instance of the class. - /// Sets up default settings for the control. - /// + /// + /// Initializes a new instance of the class. + /// Sets up default settings for the control. + /// /// The client resources controller. public DnnJsInclude(IClientResourceController clientResourceController) - : base() - { + { this.clientResourceController = clientResourceController; this.ForceProvider = ClientResourceProviders.DefaultJsProvider; - this.DependencyType = ClientDependencyType.Javascript; + this.DependencyType = ClientDependencyType.Javascript; } - protected override void OnInit(EventArgs e) - { - this.clientResourceController.CreateScript(this.FilePath, this.PathNameAlias) - .SetNameAndVersion(this.Name, this.Version, this.ForceVersion) - .SetProvider(this.ForceProvider) - .SetPriority(this.Priority) - .Register(); - } + /// + public bool Async { get; set; } + + /// + public bool Defer { get; set; } + + /// + public bool NoModule { get; set; } /// - protected override void OnLoad(System.EventArgs e) - { - this.PathNameAlias = string.IsNullOrEmpty(this.PathNameAlias) ? string.Empty : this.PathNameAlias.ToLowerInvariant(); - base.OnLoad(e); + protected override void OnLoad(System.EventArgs e) + { + var script = this.clientResourceController.CreateScript(this.FilePath, this.PathNameAlias); + if (this.Async) + { + script = script.SetAsync(); + } + + if (this.Defer) + { + script = script.SetDefer(); + } + + if (this.NoModule) + { + script = script.SetNoModule(); + } + + this.RegisterResource(script); + base.OnLoad(e); } /// - protected override void Render(HtmlTextWriter writer) - { - if (this.AddTag || this.Context.IsDebuggingEnabled) - { - writer.Write("", this.FilePath, this.ForceProvider, this.Priority); - } - } - } -} + protected override void Render(HtmlTextWriter writer) + { + if (this.AddTag || this.Context.IsDebuggingEnabled) + { + writer.Write("", this.FilePath, this.ForceProvider, this.Priority); + } + } + } +} diff --git a/DNN Platform/Website/Install/Config/10.02.00.config b/DNN Platform/Website/Install/Config/10.02.00.config index 0f12e8a6a09..c3982e97c63 100644 --- a/DNN Platform/Website/Install/Config/10.02.00.config +++ b/DNN Platform/Website/Install/Config/10.02.00.config @@ -1,8 +1,7 @@ - - + diff --git a/DNN Platform/Website/admin/Skins/DnnCssExclude.ascx.cs b/DNN Platform/Website/admin/Skins/DnnCssExclude.ascx.cs index 167776c1258..55804abe4ca 100644 --- a/DNN Platform/Website/admin/Skins/DnnCssExclude.ascx.cs +++ b/DNN Platform/Website/admin/Skins/DnnCssExclude.ascx.cs @@ -11,9 +11,9 @@ public partial class DnnCssExclude : SkinObjectBase public string Name { get; set; } /// - protected override void OnLoad(EventArgs e) + protected override void OnInit(EventArgs e) { - base.OnLoad(e); + base.OnInit(e); this.ctlExclude.Name = this.Name; } } diff --git a/DNN Platform/Website/admin/Skins/DnnCssInclude.ascx.cs b/DNN Platform/Website/admin/Skins/DnnCssInclude.ascx.cs index 80482ee689e..3cb0acec304 100644 --- a/DNN Platform/Website/admin/Skins/DnnCssInclude.ascx.cs +++ b/DNN Platform/Website/admin/Skins/DnnCssInclude.ascx.cs @@ -5,6 +5,7 @@ namespace DotNetNuke.UI.Skins.Controls { using System; + using DotNetNuke.Abstractions.ClientResources; using DotNetNuke.Web.Client.Cdf; /// A control which causes CSS to be included on the page. @@ -28,12 +29,34 @@ public partial class DnnCssInclude : SkinObjectBase public string ForceProvider { get; set; } + [Obsolete("Deprecated in DotNetNuke 10.2.0. Bundling is no longer supported, there is no replacement within DNN for this functionality. Scheduled removal in v12.0.0.")] public bool ForceBundle { get; set; } + /// Gets or sets the CDN URL of the resource. + public string CdnUrl { get; set; } + + /// Gets or sets a value indicating whether to render the blocking attribute. + public bool Blocking { get; set; } + + /// Gets or sets the integrity hash of the resource. + public string Integrity { get; set; } + + /// Gets or sets the value of the crossorigin attribute. + public CrossOrigin CrossOrigin { get; set; } + + /// Gets or sets the value of the fetchpriority attribute. + public FetchPriority FetchPriority { get; set; } + + /// Gets or sets the value of the referrerpolicy attribute. + public ReferrerPolicy ReferrerPolicy { get; set; } + + /// Gets or sets a value indicating whether the client resource should be preloaded. + public bool Preload { get; set; } + /// - protected override void OnLoad(EventArgs e) + protected override void OnInit(EventArgs e) { - base.OnLoad(e); + base.OnInit(e); this.ctlInclude.AddTag = this.AddTag; this.ctlInclude.FilePath = this.FilePath; this.ctlInclude.ForceProvider = this.ForceProvider; @@ -42,6 +65,13 @@ protected override void OnLoad(EventArgs e) this.ctlInclude.PathNameAlias = this.PathNameAlias; this.ctlInclude.Priority = this.Priority; this.ctlInclude.Version = this.Version; + this.ctlInclude.CdnUrl = this.CdnUrl; + this.ctlInclude.Blocking = this.Blocking; + this.ctlInclude.Integrity = this.Integrity; + this.ctlInclude.CrossOrigin = this.CrossOrigin; + this.ctlInclude.FetchPriority = this.FetchPriority; + this.ctlInclude.ReferrerPolicy = this.ReferrerPolicy; + this.ctlInclude.Preload = this.Preload; if (this.CssMedia != CssMediaType.None) { this.ctlInclude.CssMedia = this.CssMedia.ToString().ToLowerInvariant(); diff --git a/DNN Platform/Website/admin/Skins/DnnJsExclude.ascx.cs b/DNN Platform/Website/admin/Skins/DnnJsExclude.ascx.cs index f8148ef1313..c0bbd771b7e 100644 --- a/DNN Platform/Website/admin/Skins/DnnJsExclude.ascx.cs +++ b/DNN Platform/Website/admin/Skins/DnnJsExclude.ascx.cs @@ -11,9 +11,9 @@ public partial class DnnJsExclude : SkinObjectBase public string Name { get; set; } /// - protected override void OnLoad(EventArgs e) + protected override void OnInit(EventArgs e) { - base.OnLoad(e); + base.OnInit(e); this.ctlExclude.Name = this.Name; } } diff --git a/DNN Platform/Website/admin/Skins/DnnJsInclude.ascx.cs b/DNN Platform/Website/admin/Skins/DnnJsInclude.ascx.cs index b5ee3fdae90..5569ee782d4 100644 --- a/DNN Platform/Website/admin/Skins/DnnJsInclude.ascx.cs +++ b/DNN Platform/Website/admin/Skins/DnnJsInclude.ascx.cs @@ -5,6 +5,8 @@ namespace DotNetNuke.UI.Skins.Controls { using System; + using DotNetNuke.Abstractions.ClientResources; + /// A control which causes JavaScript to be included on the page. public partial class DnnJsInclude : SkinObjectBase { @@ -24,12 +26,40 @@ public partial class DnnJsInclude : SkinObjectBase public string ForceProvider { get; set; } + [Obsolete("Deprecated in DotNetNuke 10.2.0. Bundling is no longer supported, there is no replacement within DNN for this functionality. Scheduled removal in v12.0.0.")] public bool ForceBundle { get; set; } + /// Gets or sets the CDN URL of the resource. + public string CdnUrl { get; set; } + + /// Gets or sets a value indicating whether to render the blocking attribute. + public bool Blocking { get; set; } + + /// Gets or sets the integrity hash of the resource. + public string Integrity { get; set; } + + /// Gets or sets the value of the crossorigin attribute. + public CrossOrigin CrossOrigin { get; set; } + + /// Gets or sets the value of the fetchpriority attribute. + public FetchPriority FetchPriority { get; set; } + + /// Gets or sets the value of the referrerpolicy attribute. + public ReferrerPolicy ReferrerPolicy { get; set; } + + /// + public bool Async { get; set; } + + /// + public bool Defer { get; set; } + + /// + public bool NoModule { get; set; } + /// - protected override void OnLoad(EventArgs e) + protected override void OnInit(EventArgs e) { - base.OnLoad(e); + base.OnInit(e); this.ctlInclude.AddTag = this.AddTag; this.ctlInclude.FilePath = this.FilePath; this.ctlInclude.ForceProvider = this.ForceProvider; @@ -38,6 +68,15 @@ protected override void OnLoad(EventArgs e) this.ctlInclude.PathNameAlias = this.PathNameAlias; this.ctlInclude.Priority = this.Priority; this.ctlInclude.Version = this.Version; + this.ctlInclude.CdnUrl = this.CdnUrl; + this.ctlInclude.Blocking = this.Blocking; + this.ctlInclude.Integrity = this.Integrity; + this.ctlInclude.CrossOrigin = this.CrossOrigin; + this.ctlInclude.FetchPriority = this.FetchPriority; + this.ctlInclude.ReferrerPolicy = this.ReferrerPolicy; + this.ctlInclude.Async = this.Async; + this.ctlInclude.Defer = this.Defer; + this.ctlInclude.NoModule = this.NoModule; } } }