changes to support page level scripts, ability to detect prerendering
This commit is contained in:
@ -1,6 +1,8 @@
|
||||
@using Microsoft.AspNetCore.Http
|
||||
@inject IInstallationService InstallationService
|
||||
@inject IJSRuntime JSRuntime
|
||||
@inject SiteState SiteState
|
||||
@inject IServiceProvider ServiceProvider
|
||||
|
||||
@if (_initialized)
|
||||
{
|
||||
@ -30,35 +32,47 @@
|
||||
}
|
||||
|
||||
@code {
|
||||
[Parameter]
|
||||
public string AntiForgeryToken { get; set; }
|
||||
[Parameter]
|
||||
public string AntiForgeryToken { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string Runtime { get; set; }
|
||||
[Parameter]
|
||||
public string Runtime { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string RenderMode { get; set; }
|
||||
[Parameter]
|
||||
public string RenderMode { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public int VisitorId { get; set; }
|
||||
[Parameter]
|
||||
public int VisitorId { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string RemoteIPAddress { get; set; }
|
||||
[Parameter]
|
||||
public string RemoteIPAddress { get; set; }
|
||||
|
||||
[Parameter]
|
||||
public string AuthorizationToken { get; set; }
|
||||
[Parameter]
|
||||
public string AuthorizationToken { get; set; }
|
||||
|
||||
private bool _initialized = false;
|
||||
private string _display = "display: none;";
|
||||
private Installation _installation = new Installation { Success = false, Message = "" };
|
||||
private bool _initialized = false;
|
||||
private string _display = "display: none;";
|
||||
private Installation _installation = new Installation { Success = false, Message = "" };
|
||||
|
||||
private PageState PageState { get; set; }
|
||||
private PageState PageState { get; set; }
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
SiteState.RemoteIPAddress = RemoteIPAddress;
|
||||
SiteState.AntiForgeryToken = AntiForgeryToken;
|
||||
SiteState.AuthorizationToken = AuthorizationToken;
|
||||
private IHttpContextAccessor accessor;
|
||||
|
||||
protected override async Task OnParametersSetAsync()
|
||||
{
|
||||
SiteState.RemoteIPAddress = RemoteIPAddress;
|
||||
SiteState.AntiForgeryToken = AntiForgeryToken;
|
||||
SiteState.AuthorizationToken = AuthorizationToken;
|
||||
|
||||
accessor = (IHttpContextAccessor)ServiceProvider.GetService(typeof(IHttpContextAccessor));
|
||||
if (accessor != null)
|
||||
{
|
||||
SiteState.IsPrerendering = !accessor.HttpContext.Response.HasStarted;
|
||||
}
|
||||
else
|
||||
{
|
||||
SiteState.IsPrerendering = true;
|
||||
}
|
||||
|
||||
_installation = await InstallationService.IsInstalled();
|
||||
if (_installation.Alias != null)
|
||||
|
@ -278,6 +278,7 @@ namespace Oqtane.Modules
|
||||
SiteState.Properties.PageTitle = title;
|
||||
}
|
||||
|
||||
// note - only supports links and meta tags - not scripts
|
||||
public void AddHeadContent(string content)
|
||||
{
|
||||
if (string.IsNullOrEmpty(SiteState.Properties.HeadContent))
|
||||
|
@ -6,9 +6,9 @@
|
||||
@DynamicComponent
|
||||
|
||||
@code {
|
||||
[CascadingParameter] PageState PageState { get; set; }
|
||||
[CascadingParameter] PageState PageState { get; set; }
|
||||
|
||||
RenderFragment DynamicComponent { get; set; }
|
||||
RenderFragment DynamicComponent { get; set; }
|
||||
|
||||
protected override void OnParametersSet()
|
||||
{
|
||||
@ -38,21 +38,21 @@
|
||||
favicon = Utilities.FileUrl(PageState.Alias, PageState.Site.FaviconFileId.Value);
|
||||
}
|
||||
headcontent += $"<link id=\"app-favicon\" rel=\"shortcut icon\" type=\"image/x-icon\" href=\"{favicon}\" />\n";
|
||||
// head content
|
||||
if (!string.IsNullOrEmpty(PageState.Site.HeadContent))
|
||||
{
|
||||
headcontent += ProcessHeadContent(PageState.Site.HeadContent, "site") + "\n";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(PageState.Page.HeadContent))
|
||||
{
|
||||
headcontent += ProcessHeadContent(PageState.Page.HeadContent, $"page{PageState.Page.PageId}") + "\n";
|
||||
}
|
||||
// stylesheets
|
||||
foreach (Resource resource in PageState.Page.Resources.Where(item => item.ResourceType == ResourceType.Stylesheet))
|
||||
{
|
||||
var url = (resource.Url.Contains("://")) ? resource.Url : PageState.Alias.BaseUrl + resource.Url;
|
||||
headcontent += CreateLink(url, resource.Integrity, resource.CrossOrigin) + "\n";
|
||||
}
|
||||
// head content
|
||||
if (!string.IsNullOrEmpty(PageState.Site.HeadContent))
|
||||
{
|
||||
headcontent += PageState.Site.HeadContent + "\n";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(PageState.Page.HeadContent))
|
||||
{
|
||||
headcontent += PageState.Page.HeadContent + "\n";
|
||||
}
|
||||
SiteState.Properties.HeadContent = headcontent;
|
||||
|
||||
DynamicComponent = builder =>
|
||||
@ -65,87 +65,75 @@
|
||||
|
||||
protected override async Task OnAfterRenderAsync(bool firstRender)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
|
||||
if (!firstRender)
|
||||
{
|
||||
// inject scripts into page
|
||||
var interop = new Interop(JSRuntime);
|
||||
var count = 0;
|
||||
var index = PageState.Page.HeadContent.IndexOf("<script");
|
||||
while (index >= 0)
|
||||
if (!string.IsNullOrEmpty(PageState.Page.HeadContent) && PageState.Page.HeadContent.Contains("<script"))
|
||||
{
|
||||
var script = PageState.Page.HeadContent.Substring(index, PageState.Page.HeadContent.IndexOf("</script>", index) + 9 - index);
|
||||
var attributes = script.Substring(0, script.IndexOf(">")).Replace("\"", "").Split(" ");
|
||||
string id = "";
|
||||
string src = "";
|
||||
string integrity = "";
|
||||
string crossorigin = "";
|
||||
string type = "";
|
||||
foreach (var attribute in attributes)
|
||||
// inject scripts into page dynamically
|
||||
var interop = new Interop(JSRuntime);
|
||||
var scripts = new List<object>();
|
||||
var count = 0;
|
||||
var index = PageState.Page.HeadContent.IndexOf("<script");
|
||||
while (index >= 0)
|
||||
{
|
||||
if (attribute.Contains("="))
|
||||
var script = PageState.Page.HeadContent.Substring(index, PageState.Page.HeadContent.IndexOf("</script>", index) + 9 - index);
|
||||
// get script attributes
|
||||
var attributes = script.Substring(0, script.IndexOf(">")).Replace("\"", "").Split(" ");
|
||||
string id = "";
|
||||
string src = "";
|
||||
string integrity = "";
|
||||
string crossorigin = "";
|
||||
string type = "";
|
||||
foreach (var attribute in attributes)
|
||||
{
|
||||
var value = attribute.Split("=");
|
||||
switch (value[0])
|
||||
if (attribute.Contains("="))
|
||||
{
|
||||
case "id":
|
||||
id = value[1];
|
||||
break;
|
||||
case "src":
|
||||
src = value[1];
|
||||
break;
|
||||
case "integrity":
|
||||
integrity = value[1];
|
||||
break;
|
||||
case "crossorigin":
|
||||
crossorigin = value[1];
|
||||
break;
|
||||
case "type":
|
||||
type = value[1];
|
||||
break;
|
||||
var value = attribute.Split("=");
|
||||
switch (value[0])
|
||||
{
|
||||
case "id":
|
||||
id = value[1];
|
||||
break;
|
||||
case "src":
|
||||
src = value[1];
|
||||
break;
|
||||
case "integrity":
|
||||
integrity = value[1];
|
||||
break;
|
||||
case "crossorigin":
|
||||
crossorigin = value[1];
|
||||
break;
|
||||
case "type":
|
||||
type = value[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(src))
|
||||
{
|
||||
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
||||
await interop.IncludeScript(id, src, integrity, crossorigin, type, "", "head");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (id == "")
|
||||
// inject script
|
||||
if (!string.IsNullOrEmpty(src))
|
||||
{
|
||||
count += 1;
|
||||
id = $"page{PageState.Page.PageId}-script{count}";
|
||||
src = (src.Contains("://")) ? src : PageState.Alias.BaseUrl + src;
|
||||
scripts.Add(new { href = src, bundle = "", integrity = integrity, crossorigin = crossorigin, es6module = (type == "module"), location = "head" });
|
||||
}
|
||||
index = script.IndexOf(">") + 1;
|
||||
await interop.IncludeScript(id, "", "", "", "", script.Substring(index, script.IndexOf("</script>") - index), "head");
|
||||
else
|
||||
{
|
||||
// inline script must have an id attribute
|
||||
if (id == "")
|
||||
{
|
||||
count += 1;
|
||||
id = $"page{PageState.Page.PageId}-script{count}";
|
||||
}
|
||||
index = script.IndexOf(">") + 1;
|
||||
await interop.IncludeScript(id, "", "", "", "", script.Substring(index, script.IndexOf("</script>") - index), "head");
|
||||
}
|
||||
index = PageState.Page.HeadContent.IndexOf("<script", index + 1);
|
||||
}
|
||||
index = PageState.Page.HeadContent.IndexOf("<script", index + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string ProcessHeadContent(string headcontent, string id)
|
||||
{
|
||||
// iterate scripts
|
||||
if (!string.IsNullOrEmpty(headcontent))
|
||||
{
|
||||
var count = 0;
|
||||
var index = headcontent.IndexOf("<script");
|
||||
while (index >= 0)
|
||||
{
|
||||
var script = headcontent.Substring(index, headcontent.IndexOf("</script>", index) + 9 - index);
|
||||
if (!script.Contains("src=") && !script.Contains("id="))
|
||||
if (scripts.Any())
|
||||
{
|
||||
count += 1;
|
||||
id += $"-script{count}";
|
||||
headcontent = headcontent.Replace(script, script.Replace("<script", $"<script id=\"{id}\""));
|
||||
index += id.Length;
|
||||
await interop.IncludeScripts(scripts.ToArray());
|
||||
}
|
||||
index = headcontent.IndexOf("<script", index + 1);
|
||||
}
|
||||
}
|
||||
return headcontent;
|
||||
}
|
||||
|
||||
private string CreateLink(string url, string integrity, string crossorigin)
|
||||
|
Reference in New Issue
Block a user