Central management of resources ( ie. stylesheets and scripts )
This commit is contained in:
parent
1b2600c6c4
commit
54d4447d23
|
@ -28,9 +28,19 @@
|
||||||
@code {
|
@code {
|
||||||
public override string Panes => "Content";
|
public override string Panes => "Content";
|
||||||
|
|
||||||
|
public override List<Resource> Resources
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<Resource> resources = new List<Resource>();
|
||||||
|
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "Themes/" + GetType().Namespace + "/Theme.css", Integrity = "", CrossOrigin = "" });
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
await IncludeCSS("Theme.css");
|
//await IncludeCSS("Theme.css");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -19,11 +19,22 @@
|
||||||
@code {
|
@code {
|
||||||
public override string Panes => string.Empty;
|
public override string Panes => string.Empty;
|
||||||
|
|
||||||
|
public override List<Resource> Resources
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
List<Resource> resources = new List<Resource>();
|
||||||
|
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css", Integrity = "sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM", CrossOrigin = "anonymous" });
|
||||||
|
resources.Add(new Resource { ResourceType = ResourceType.Stylesheet, Url = "Themes/" + GetType().Namespace + "/Theme.css" });
|
||||||
|
return resources;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
// go to https://www.bootstrapcdn.com/bootswatch/ and take your favorite theme
|
// go to https://www.bootstrapcdn.com/bootswatch/ and take your favorite theme
|
||||||
//<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css" rel="stylesheet" integrity="sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM" crossorigin="anonymous">
|
//<link href="https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css" rel="stylesheet" integrity="sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM" crossorigin="anonymous">
|
||||||
await LoadBootstrapTheme("https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css","sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM");
|
//await LoadBootstrapTheme("https://stackpath.bootstrapcdn.com/bootswatch/4.4.1/cyborg/bootstrap.min.css","sha384-l7xaoY0cJM4h9xh1RfazbgJVUZvdtyLWPueWNtLAphf/UbBgOVzqbOTogxPwYLHM");
|
||||||
await IncludeCSS("Theme.css");
|
//await IncludeCSS("Theme.css");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.JSInterop;
|
using Microsoft.JSInterop;
|
||||||
|
using Oqtane.Models;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
using Oqtane.UI;
|
using Oqtane.UI;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Oqtane.Themes
|
namespace Oqtane.Themes
|
||||||
|
@ -14,6 +16,7 @@ namespace Oqtane.Themes
|
||||||
[CascadingParameter]
|
[CascadingParameter]
|
||||||
protected PageState PageState { get; set; }
|
protected PageState PageState { get; set; }
|
||||||
public virtual string Panes { get; set; }
|
public virtual string Panes { get; set; }
|
||||||
|
public virtual List<Resource> Resources { get; set; }
|
||||||
|
|
||||||
public string ThemePath()
|
public string ThemePath()
|
||||||
{
|
{
|
||||||
|
|
|
@ -118,6 +118,22 @@ namespace Oqtane.UI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task RemoveElementsById(string prefix, string first, string last)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_jsRuntime.InvokeAsync<string>(
|
||||||
|
"interop.removeElementsById",
|
||||||
|
prefix, first, last);
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public ValueTask<string> GetElementByName(string name)
|
public ValueTask<string> GetElementByName(string name)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
@ -355,19 +355,30 @@
|
||||||
page.ThemeType = site.DefaultThemeType;
|
page.ThemeType = site.DefaultThemeType;
|
||||||
page.LayoutType = site.DefaultLayoutType;
|
page.LayoutType = site.DefaultLayoutType;
|
||||||
}
|
}
|
||||||
Type type;
|
|
||||||
|
page.Resources = new List<Resource>();
|
||||||
|
|
||||||
|
Type themetype = Type.GetType(page.ThemeType);
|
||||||
|
var themeobject = Activator.CreateInstance(themetype);
|
||||||
|
if (themeobject != null)
|
||||||
|
{
|
||||||
|
page.Panes = (string)themetype.GetProperty("Panes").GetValue(themeobject, null);
|
||||||
|
var resources = (List<Resource>)themetype.GetProperty("Resources").GetValue(themeobject, null);
|
||||||
|
if (resources != null)
|
||||||
|
{
|
||||||
|
page.Resources.AddRange(resources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(page.LayoutType))
|
if (!string.IsNullOrEmpty(page.LayoutType))
|
||||||
{
|
{
|
||||||
type = Type.GetType(page.LayoutType);
|
themetype = Type.GetType(page.LayoutType);
|
||||||
}
|
themeobject = Activator.CreateInstance(themetype);
|
||||||
else
|
if (themeobject != null)
|
||||||
{
|
{
|
||||||
type = Type.GetType(page.ThemeType);
|
page.Panes = (string)themetype.GetProperty("Panes").GetValue(themeobject, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var property = type.GetProperty("Panes");
|
|
||||||
page.Panes = (string)property.GetValue(Activator.CreateInstance(type), null);
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
protected override async Task OnParametersSetAsync()
|
protected override async Task OnParametersSetAsync()
|
||||||
{
|
{
|
||||||
var interop = new Interop(JsRuntime);
|
var interop = new Interop(JsRuntime);
|
||||||
|
|
||||||
|
// set page title
|
||||||
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
if (!string.IsNullOrEmpty(PageState.Page.Title))
|
||||||
{
|
{
|
||||||
await interop.UpdateTitle(PageState.Page.Title);
|
await interop.UpdateTitle(PageState.Page.Title);
|
||||||
|
@ -20,10 +22,30 @@
|
||||||
{
|
{
|
||||||
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
await interop.UpdateTitle(PageState.Site.Name + " - " + PageState.Page.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// manage page resources- they cannot be removed first and then added because the browser will "flash" and result in a poor user experience - they need to be updated
|
||||||
|
int index = 0;
|
||||||
|
foreach (Resource resource in PageState.Page.Resources)
|
||||||
|
{
|
||||||
|
index += 1;
|
||||||
|
switch (resource.ResourceType)
|
||||||
|
{
|
||||||
|
case ResourceType.Stylesheet:
|
||||||
|
await interop.IncludeLink("app-resource" + index.ToString("00"), "stylesheet", resource.Url, "text/css", resource.Integrity, resource.CrossOrigin);
|
||||||
|
break;
|
||||||
|
case ResourceType.Script:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// remove any page resources references which are no longer required for this page
|
||||||
|
await interop.RemoveElementsById("app-resource", "app-resource" + (index + 1).ToString("00"), "");
|
||||||
|
|
||||||
|
// add favicon
|
||||||
if (PageState.Site.FaviconFileId != null)
|
if (PageState.Site.FaviconFileId != null)
|
||||||
{
|
{
|
||||||
await interop.IncludeLink("fav-icon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "");
|
await interop.IncludeLink("fav-icon", "shortcut icon", Utilities.ContentUrl(PageState.Alias, PageState.Site.FaviconFileId.Value), "image/x-icon", "", "");
|
||||||
}
|
}
|
||||||
|
// add PWA support
|
||||||
if (PageState.Site.PwaIsEnabled)
|
if (PageState.Site.PwaIsEnabled)
|
||||||
{
|
{
|
||||||
await InitializePwa(interop);
|
await InitializePwa(interop);
|
||||||
|
|
|
@ -160,6 +160,15 @@ window.interop = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
removeElementsById: function (prefix, first, last) {
|
||||||
|
var elements = document.querySelectorAll('[id^=' + prefix + ']');
|
||||||
|
for (var i = elements.length - 1; i >= 0; i--) {
|
||||||
|
var element = elements[i];
|
||||||
|
if (element.id.startsWith(prefix) && (first === '' || element.id >= first) && (last === '' || element.id <= last)) {
|
||||||
|
element.parentNode.removeChild(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
getElementByName: function (name) {
|
getElementByName: function (name) {
|
||||||
var elements = document.getElementsByName(name);
|
var elements = document.getElementsByName(name);
|
||||||
if (elements.length) {
|
if (elements.length) {
|
||||||
|
|
8
Oqtane.Shared/Enums/ResourceType.cs
Normal file
8
Oqtane.Shared/Enums/ResourceType.cs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
namespace Oqtane.Shared
|
||||||
|
{
|
||||||
|
public enum ResourceType
|
||||||
|
{
|
||||||
|
Stylesheet,
|
||||||
|
Script
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,11 @@
|
||||||
namespace Oqtane.Themes
|
using Oqtane.Models;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Oqtane.Themes
|
||||||
{
|
{
|
||||||
public interface IThemeControl
|
public interface IThemeControl
|
||||||
{
|
{
|
||||||
string Panes { get; } // identifies all panes in a theme ( delimited by ";" ) - assumed to be a layout if no panes specified
|
string Panes { get; } // identifies all panes in a theme ( delimited by ";" ) - assumed to be a layout if no panes specified
|
||||||
|
List<Resource> Resources { get; } // identifies all resources in a theme
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
namespace Oqtane.Models
|
namespace Oqtane.Models
|
||||||
|
@ -33,6 +34,8 @@ namespace Oqtane.Models
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public string Panes { get; set; }
|
public string Panes { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
|
public List<Resource> Resources { get; set; }
|
||||||
|
[NotMapped]
|
||||||
public string Permissions { get; set; }
|
public string Permissions { get; set; }
|
||||||
[NotMapped]
|
[NotMapped]
|
||||||
public int Level { get; set; }
|
public int Level { get; set; }
|
||||||
|
|
12
Oqtane.Shared/Models/Resource.cs
Normal file
12
Oqtane.Shared/Models/Resource.cs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
using Oqtane.Shared;
|
||||||
|
|
||||||
|
namespace Oqtane.Models
|
||||||
|
{
|
||||||
|
public class Resource
|
||||||
|
{
|
||||||
|
public ResourceType ResourceType { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public string Integrity { get; set; }
|
||||||
|
public string CrossOrigin { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
namespace Oqtane.Models
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Oqtane.Models
|
||||||
{
|
{
|
||||||
public class Theme
|
public class Theme
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user