public Action <TemplateScopeContext, object, object> GetAssignExpression(Type targetType, ReadOnlyMemory <char> expression) { if (targetType == null) { throw new ArgumentNullException(nameof(targetType)); } if (expression.IsNullOrWhiteSpace()) { throw new ArgumentNullException(nameof(expression)); } var key = targetType.FullName + ':' + expression; if (AssignExpressionCache.TryGetValue(key, out var fn)) { return(fn); } AssignExpressionCache[key] = fn = TemplatePageUtils.CompileAssign(targetType, expression); return(fn); }
public Func <TemplateScopeContext, object, object> GetExpressionBinder(Type targetType, StringSegment expression) { if (targetType == null) { throw new ArgumentNullException(nameof(targetType)); } if (expression.IsNullOrWhiteSpace()) { throw new ArgumentNullException(nameof(expression)); } var key = targetType.FullName + ':' + expression; if (BinderCache.TryGetValue(key, out Func <TemplateScopeContext, object, object> fn)) { return(fn); } BinderCache[key] = fn = TemplatePageUtils.Compile(targetType, expression); return(fn); }
public async Task <TemplatePage> Load() { string contents; using (var stream = File.OpenRead()) { contents = await stream.ReadToEndAsync(); } var lastModified = File.LastModified; var fileContents = contents.AsMemory(); var pageVars = new Dictionary <string, object>(); var pos = 0; var bodyContents = fileContents; fileContents.AdvancePastWhitespace().TryReadLine(out ReadOnlyMemory <char> line, ref pos); if (line.StartsWith(Format.ArgsPrefix)) { while (fileContents.TryReadLine(out line, ref pos)) { if (line.Trim().Length == 0) { continue; } if (line.StartsWith(Format.ArgsSuffix)) { break; } line.SplitOnFirst(':', out var first, out var last); pageVars[first.Trim().ToString()] = !last.IsEmpty ? last.Trim().ToString() : ""; } //When page has variables body starts from first non whitespace after variable's end var argsSuffixPos = line.LastIndexOf(Format.ArgsSuffix); if (argsSuffixPos >= 0) { //Start back from the end of the ArgsSuffix pos -= line.Length - argsSuffixPos - Format.ArgsSuffix.Length; } bodyContents = fileContents.SafeSlice(pos).AdvancePastWhitespace(); } var pageFragments = pageVars.TryGetValue("ignore", out object ignore) && ("page".Equals(ignore.ToString()) || "template".Equals(ignore.ToString())) ? new List <PageFragment> { new PageStringFragment(bodyContents) } : TemplatePageUtils.ParseTemplatePage(bodyContents); foreach (var fragment in pageFragments) { if (fragment is PageVariableFragment var && var.Binding == TemplateConstants.Page) { IsLayout = true; break; } } lock (semaphore) { LastModified = lastModified; LastModifiedCheck = DateTime.UtcNow; FileContents = fileContents; Args = pageVars; BodyContents = bodyContents; PageFragments = pageFragments; HasInit = true; LayoutPage = Format.ResolveLayout(this); } if (LayoutPage != null) { if (!LayoutPage.HasInit) { await LayoutPage.Load(); } else { if (Context.DebugMode || Context.CheckForModifiedPagesAfter != null && DateTime.UtcNow - LayoutPage.LastModifiedCheck >= Context.CheckForModifiedPagesAfter.Value) { LayoutPage.File.Refresh(); LayoutPage.LastModifiedCheck = DateTime.UtcNow; if (LayoutPage.File.LastModified != LayoutPage.LastModified) { await LayoutPage.Load(); } } } } return(this); }
public async Task <TemplatePage> Load() { string serverHtml; using (var stream = File.OpenRead()) using (var reader = new StreamReader(stream, Encoding.UTF8)) { serverHtml = await reader.ReadToEndAsync(); } lock (semaphore) { LastModified = File.LastModified; ServerHtml = serverHtml.ToStringSegment(); PageVars = new Dictionary <string, string>(); var pos = 0; while (char.IsWhiteSpace(ServerHtml.GetChar(pos))) { pos++; } ServerHtml.TryReadLine(out StringSegment line, ref pos); if (line.StartsWith("<!--")) { while (ServerHtml.TryReadLine(out line, ref pos)) { if (line.Trim().Length == 0) { continue; } if (line.StartsWith("-->")) { break; } var kvp = line.SplitOnFirst(':'); PageVars[kvp[0].Trim().ToString()] = kvp.Length > 1 ? kvp[1].Trim().ToString() : ""; } } else { pos = 0; } PageHtml = ServerHtml.Subsegment(pos).TrimStart(); PageFragments = TemplatePageUtils.ParseTemplatePage(PageHtml); IsCompletePage = Context.IsCompletePage(PageHtml); HasInit = true; if (!IsCompletePage) { if (PageVars.TryGetValue(TemplatePages.Layout, out string layout)) { Layout = layout; } LayoutPage = Context.TemplatePages.ResolveLayoutPage(this); } } if (LayoutPage != null) { if (!LayoutPage.HasInit) { await LayoutPage.Load(); } else if (Context.CheckModifiedPages || Context.DebugMode) { LayoutPage.File.Refresh(); if (LayoutPage.File.LastModified > LayoutPage.LastModified) { await LayoutPage.Load(); } } } return(this); }
public async Task <TemplatePage> Load() { string contents; using (var stream = File.OpenRead()) using (var reader = new StreamReader(stream, Encoding.UTF8)) { contents = await reader.ReadToEndAsync(); } var lastModified = File.LastModified; var fileContents = contents.ToStringSegment(); var pageVars = new Dictionary <string, object>(); var pos = 0; var bodyContents = fileContents; fileContents.AdvancePastWhitespace().TryReadLine(out StringSegment line, ref pos); if (line.StartsWith(Format.ArgsPrefix)) { while (fileContents.TryReadLine(out line, ref pos)) { if (line.Trim().Length == 0) { continue; } if (line.StartsWith(Format.ArgsSuffix)) { break; } var kvp = line.SplitOnFirst(':'); pageVars[kvp[0].Trim().ToString()] = kvp.Length > 1 ? kvp[1].Trim().ToString() : ""; } //When page has variables body starts from first non whitespace after variable's end bodyContents = fileContents.SafeSubsegment(pos).AdvancePastWhitespace(); } var pageFragments = pageVars.TryGetValue("ignore", out object ignore) && ("page".Equals(ignore.ToString()) || "template".Equals(ignore.ToString())) ? new List <PageFragment> { new PageStringFragment(bodyContents) } : TemplatePageUtils.ParseTemplatePage(bodyContents); foreach (var fragment in pageFragments) { if (fragment is PageVariableFragment var && var.BindingString == TemplateConstants.Page) { IsLayout = true; break; } } lock (semaphore) { LastModified = lastModified; LastModifiedCheck = DateTime.UtcNow; FileContents = fileContents; Args = pageVars; BodyContents = bodyContents; PageFragments = pageFragments; HasInit = true; LayoutPage = Format.ResolveLayout(this); } if (LayoutPage != null) { if (!LayoutPage.HasInit) { await LayoutPage.Load(); } else { if (Context.DebugMode || Context.CheckForModifiedPagesAfter != null && DateTime.UtcNow - LayoutPage.LastModifiedCheck >= Context.CheckForModifiedPagesAfter.Value) { LayoutPage.File.Refresh(); LayoutPage.LastModifiedCheck = DateTime.UtcNow; if (LayoutPage.File.LastModified != LayoutPage.LastModified) { await LayoutPage.Load(); } } } } return(this); }
public async Task <TemplatePage> Load() { string contents; using (var stream = File.OpenRead()) using (var reader = new StreamReader(stream, Encoding.UTF8)) { contents = await reader.ReadToEndAsync(); } var lastModified = File.LastModified; var fileContents = contents.ToStringSegment(); var pageVars = new Dictionary <string, object>(); var pos = 0; while (char.IsWhiteSpace(fileContents.GetChar(pos))) { pos++; } fileContents.TryReadLine(out StringSegment line, ref pos); if (line.StartsWith(Format.ArgsPrefix)) { while (fileContents.TryReadLine(out line, ref pos)) { if (line.Trim().Length == 0) { continue; } if (line.StartsWith(Format.ArgsSuffix)) { break; } var kvp = line.SplitOnFirst(':'); pageVars[kvp[0].Trim().ToString()] = kvp.Length > 1 ? kvp[1].Trim().ToString() : ""; } } else { pos = 0; } var bodyContents = fileContents.Subsegment(pos).TrimStart(); var pageFragments = TemplatePageUtils.ParseTemplatePage(bodyContents); lock (semaphore) { LastModified = lastModified; FileContents = fileContents; Args = pageVars; BodyContents = bodyContents; PageFragments = pageFragments; HasInit = true; LayoutPage = Format.ResolveLayout(this); } if (LayoutPage != null) { if (!LayoutPage.HasInit) { await LayoutPage.Load(); } else if (Context.CheckForModifiedPages || Context.DebugMode) { LayoutPage.File.Refresh(); if (LayoutPage.File.LastModified != LayoutPage.LastModified) { await LayoutPage.Load(); } } } return(this); }