\n`}tablecell(e){const t=this.parser.parseInline(e.tokens),n=e.header?"th":"td";return(e.align?`<${n} align="${e.align}">`:`<${n}>`)+t+`${n}>\n`}strong({tokens:e}){return`${this.parser.parseInline(e)}`}em({tokens:e}){return`${this.parser.parseInline(e)}`}codespan({text:e}){return`${W(e,!0)}`}br(e){return" "}del({tokens:e}){return`${this.parser.parseInline(e)}`}link({href:e,title:t,tokens:n}){const s=this.parser.parseInline(n),r=Y(e);if(null===r)return s;let i='"+s+"",i}image({href:e,title:t,text:n}){const s=Y(e);if(null===s)return W(n);let r=`",r}text(e){return"tokens"in e&&e.tokens?this.parser.parseInline(e.tokens):"escaped"in e&&e.escaped?e.text:W(e.text)}}class le{strong({text:e}){return e}em({text:e}){return e}codespan({text:e}){return e}del({text:e}){return e}html({text:e}){return e}text({text:e}){return e}link({text:e}){return""+e}image({text:e}){return""+e}br(){return""}}class oe{options;renderer;textRenderer;constructor(t){this.options=t||e.defaults,this.options.renderer=this.options.renderer||new ie,this.renderer=this.options.renderer,this.renderer.options=this.options,this.renderer.parser=this,this.textRenderer=new le}static parse(e,t){return new oe(t).parse(e)}static parseInline(e,t){return new oe(t).parseInline(e)}parse(e,t=!0){let n="";for(let s=0;s{const r=e[s].flat(1/0);n=n.concat(this.walkTokens(r,t))})):e.tokens&&(n=n.concat(this.walkTokens(e.tokens,t)))}}return n}use(...e){const t=this.defaults.extensions||{renderers:{},childTokens:{}};return e.forEach((e=>{const n={...e};if(n.async=this.defaults.async||n.async||!1,e.extensions&&(e.extensions.forEach((e=>{if(!e.name)throw new Error("extension name required");if("renderer"in e){const n=t.renderers[e.name];t.renderers[e.name]=n?function(...t){let s=e.renderer.apply(this,t);return!1===s&&(s=n.apply(this,t)),s}:e.renderer}if("tokenizer"in e){if(!e.level||"block"!==e.level&&"inline"!==e.level)throw new Error("extension level must be 'block' or 'inline'");const n=t[e.level];n?n.unshift(e.tokenizer):t[e.level]=[e.tokenizer],e.start&&("block"===e.level?t.startBlock?t.startBlock.push(e.start):t.startBlock=[e.start]:"inline"===e.level&&(t.startInline?t.startInline.push(e.start):t.startInline=[e.start]))}"childTokens"in e&&e.childTokens&&(t.childTokens[e.name]=e.childTokens)})),n.extensions=t),e.renderer){const t=this.defaults.renderer||new ie(this.defaults);for(const n in e.renderer){if(!(n in t))throw new Error(`renderer '${n}' does not exist`);if(["options","parser"].includes(n))continue;const s=n,r=e.renderer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n||""}}n.renderer=t}if(e.tokenizer){const t=this.defaults.tokenizer||new se(this.defaults);for(const n in e.tokenizer){if(!(n in t))throw new Error(`tokenizer '${n}' does not exist`);if(["options","rules","lexer"].includes(n))continue;const s=n,r=e.tokenizer[s],i=t[s];t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.tokenizer=t}if(e.hooks){const t=this.defaults.hooks||new ae;for(const n in e.hooks){if(!(n in t))throw new Error(`hook '${n}' does not exist`);if(["options","block"].includes(n))continue;const s=n,r=e.hooks[s],i=t[s];ae.passThroughHooks.has(n)?t[s]=e=>{if(this.defaults.async)return Promise.resolve(r.call(t,e)).then((e=>i.call(t,e)));const n=r.call(t,e);return i.call(t,n)}:t[s]=(...e)=>{let n=r.apply(t,e);return!1===n&&(n=i.apply(t,e)),n}}n.hooks=t}if(e.walkTokens){const t=this.defaults.walkTokens,s=e.walkTokens;n.walkTokens=function(e){let n=[];return n.push(s.call(this,e)),t&&(n=n.concat(t.call(this,e))),n}}this.defaults={...this.defaults,...n}})),this}setOptions(e){return this.defaults={...this.defaults,...e},this}lexer(e,t){return re.lex(e,t??this.defaults)}parser(e,t){return oe.parse(e,t??this.defaults)}parseMarkdown(e){return(t,n)=>{const s={...n},r={...this.defaults,...s},i=this.onError(!!r.silent,!!r.async);if(!0===this.defaults.async&&!1===s.async)return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));if(null==t)return i(new Error("marked(): input parameter is undefined or null"));if("string"!=typeof t)return i(new Error("marked(): input parameter is of type "+Object.prototype.toString.call(t)+", string expected"));r.hooks&&(r.hooks.options=r,r.hooks.block=e);const l=r.hooks?r.hooks.provideLexer():e?re.lex:re.lexInline,o=r.hooks?r.hooks.provideParser():e?oe.parse:oe.parseInline;if(r.async)return Promise.resolve(r.hooks?r.hooks.preprocess(t):t).then((e=>l(e,r))).then((e=>r.hooks?r.hooks.processAllTokens(e):e)).then((e=>r.walkTokens?Promise.all(this.walkTokens(e,r.walkTokens)).then((()=>e)):e)).then((e=>o(e,r))).then((e=>r.hooks?r.hooks.postprocess(e):e)).catch(i);try{r.hooks&&(t=r.hooks.preprocess(t));let e=l(t,r);r.hooks&&(e=r.hooks.processAllTokens(e)),r.walkTokens&&this.walkTokens(e,r.walkTokens);let n=o(e,r);return r.hooks&&(n=r.hooks.postprocess(n)),n}catch(e){return i(e)}}}onError(e,t){return n=>{if(n.message+="\nPlease report this to https://github.com/markedjs/marked.",e){const e="
An error occurred:
"+W(n.message+"",!0)+"
";return t?Promise.resolve(e):e}if(t)return Promise.reject(n);throw n}}}const he=new ce;function pe(e,t){return he.parse(e,t)}pe.options=pe.setOptions=function(e){return he.setOptions(e),pe.defaults=he.defaults,n(pe.defaults),pe},pe.getDefaults=t,pe.defaults=e.defaults,pe.use=function(...e){return he.use(...e),pe.defaults=he.defaults,n(pe.defaults),pe},pe.walkTokens=function(e,t){return he.walkTokens(e,t)},pe.parseInline=he.parseInline,pe.Parser=oe,pe.parser=oe.parse,pe.Renderer=ie,pe.TextRenderer=le,pe.Lexer=re,pe.lexer=re.lex,pe.Tokenizer=se,pe.Hooks=ae,pe.parse=pe;const ue=pe.options,ge=pe.setOptions,ke=pe.use,de=pe.walkTokens,fe=pe.parseInline,xe=pe,be=oe.parse,we=re.lex;e.Hooks=ae,e.Lexer=re,e.Marked=ce,e.Parser=oe,e.Renderer=ie,e.TextRenderer=le,e.Tokenizer=se,e.getDefaults=t,e.lexer=we,e.marked=pe,e.options=ue,e.parse=xe,e.parseInline=fe,e.parser=be,e.setOptions=ge,e.use=ke,e.walkTokens=de}));
diff --git a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeExtensions.cs
index 9087399658..ad822d6354 100644
--- a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeExtensions.cs
+++ b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeExtensions.cs
@@ -1,37 +1,42 @@
-using System.Diagnostics.CodeAnalysis;
+using System.Reflection;
+using System.Diagnostics.CodeAnalysis;
namespace Bit.BlazorUI;
public static class IJSRuntimeExtensions
{
+ public const DynamicallyAccessedMemberTypes JsonSerialized = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties;
+
+
+
///
/// Only tries to Invoke the js call when the runtime is valid.
///
- public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
+ public static ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
{
- if (jsRuntime.IsRuntimeInvalid()) return;
+ if (jsRuntime.IsRuntimeInvalid()) return ValueTask.CompletedTask;
- await jsRuntime.InvokeVoidAsync(identifier, args);
+ return jsRuntime.InvokeVoidAsync(identifier, args);
}
///
/// Only tries to Invoke the js call when the runtime is valid.
///
- public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
+ public static ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
{
- if (jsRuntime.IsRuntimeInvalid()) return;
+ if (jsRuntime.IsRuntimeInvalid()) return ValueTask.CompletedTask;
- await jsRuntime.InvokeVoidAsync(identifier, timeout, args);
+ return jsRuntime.InvokeVoidAsync(identifier, timeout, args);
}
///
/// Only tries to Invoke the js call when the runtime is valid.
///
- public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
+ public static ValueTask InvokeVoid(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
{
- if (jsRuntime.IsRuntimeInvalid()) return;
+ if (jsRuntime.IsRuntimeInvalid()) return ValueTask.CompletedTask;
- await jsRuntime.InvokeVoidAsync(identifier, cancellationToken, args);
+ return jsRuntime.InvokeVoidAsync(identifier, cancellationToken, args);
}
@@ -39,7 +44,7 @@ public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string ident
///
/// Only tries to Invoke the js call when the runtime is valid.
///
- public static ValueTask Invoke<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
+ public static ValueTask Invoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
{
if (jsRuntime.IsRuntimeInvalid()) return default;
@@ -49,7 +54,7 @@ public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string ident
///
/// Only tries to Invoke the js call when the runtime is valid.
///
- public static ValueTask InvokeAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
+ public static ValueTask Invoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
{
if (jsRuntime.IsRuntimeInvalid()) return default;
@@ -59,7 +64,7 @@ public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string ident
///
/// Only tries to Invoke the js call when the runtime is valid.
///
- public static ValueTask InvokeAsync<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
+ public static ValueTask Invoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
{
if (jsRuntime.IsRuntimeInvalid()) return default;
@@ -69,15 +74,18 @@ public static async ValueTask InvokeVoid(this IJSRuntime jsRuntime, string ident
[SuppressMessage("Trimming", "IL2075:'this' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to target method. The return value of the source method does not have matching annotations.", Justification = "")]
- internal static bool IsRuntimeInvalid(this IJSRuntime jsRuntime)
+ public static bool IsRuntimeInvalid(this IJSRuntime jsRuntime)
{
+ if (jsRuntime is null) return false;
+
var type = jsRuntime.GetType();
return type.Name switch
{
"UnsupportedJavaScriptRuntime" => true, // Prerendering
"RemoteJSRuntime" => (bool)type.GetProperty("IsInitialized")!.GetValue(jsRuntime)! is false, // Blazor server
- _ => false // Blazor WASM/Hybrid
+ "WebViewJSRuntime" => type.GetField("_ipcSender", BindingFlags.NonPublic | BindingFlags.Instance)!.GetValue(jsRuntime) is null, // Blazor Hybrid
+ _ => false // Blazor WASM
};
}
}
diff --git a/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeFastExtensions.cs b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeFastExtensions.cs
new file mode 100644
index 0000000000..3c018f9ab0
--- /dev/null
+++ b/src/BlazorUI/Bit.BlazorUI/Extensions/JsInterop/IJSRuntimeFastExtensions.cs
@@ -0,0 +1,131 @@
+using System.Text.Json;
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.JSInterop.Infrastructure;
+
+namespace Bit.BlazorUI;
+
+[SuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "", Scope = "member", Target = "~M:Bit.BlazorUI.IJSRuntimeFastExtensions.FastInvokeVoid(Microsoft.JSInterop.IJSRuntime,System.String,System.Threading.CancellationToken,System.Object[])~System.Threading.Tasks.ValueTask")]
+public static class IJSRuntimeFastExtensions
+{
+ public const DynamicallyAccessedMemberTypes JsonSerialized = DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties;
+
+
+
+ ///
+ /// Invokes the specified JavaScript function with the fastest speed possible.
+ ///
+ /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction.
+ /// JSON-serializable arguments.
+ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
+ {
+ return FastInvokeVoid(jsRuntime, identifier, CancellationToken.None, args);
+ }
+
+ ///
+ /// Invokes the specified JavaScript function with the fastest speed possible.
+ ///
+ /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction.
+ /// The duration after which to cancel the async operation. Overrides default timeouts ().
+ /// JSON-serializable arguments.
+ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
+ {
+ using var cancellationTokenSource = timeout == Timeout.InfiniteTimeSpan ? null : new CancellationTokenSource(timeout);
+ var cancellationToken = cancellationTokenSource?.Token ?? CancellationToken.None;
+
+ return FastInvokeVoid(jsRuntime, identifier, cancellationToken, args);
+ }
+
+ ///
+ /// Invokes the specified JavaScript function with the fastest speed possible.
+ ///
+ /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction.
+ ///
+ /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts
+ /// () from being applied.
+ ///
+ /// JSON-serializable arguments.
+ public static ValueTask FastInvokeVoid(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
+ {
+ if (jsRuntime is IJSInProcessRuntime jsInProcessRuntime)
+ {
+ try
+ {
+ jsInProcessRuntime.Invoke(identifier, args);
+ return ValueTask.CompletedTask;
+ }
+ catch (JsonException ex)
+ {
+ System.Console.Error.WriteLine($"Error invoking '{identifier}' using {nameof(IJSInProcessRuntime)}. A JSON-related issue occurred: {ex.Message}.");
+ return ValueTask.CompletedTask;
+ }
+ }
+ else
+ {
+ return jsRuntime.InvokeVoid(identifier, cancellationToken, args);
+ }
+ }
+
+
+
+ ///
+ /// Invokes the specified JavaScript function with the fastest speed possible.
+ /// Note: In Blazor WebAssembly mode, use this method only for synchronous JavaScript functions.
+ ///
+ /// The JSON-serializable return type.
+ /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction.
+ /// JSON-serializable arguments.
+ /// An instance of obtained by JSON-deserializing the return value.
+ public static ValueTask FastInvoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, params object?[]? args)
+ {
+ return FastInvoke(jsRuntime, identifier, CancellationToken.None, args);
+ }
+
+ ///
+ /// Invokes the specified JavaScript function with the fastest speed possible.
+ /// Note: In Blazor WebAssembly mode, use this method only for synchronous JavaScript functions.
+ ///
+ /// The JSON-serializable return type.
+ /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction.
+ /// The duration after which to cancel the async operation. Overrides default timeouts ().
+ /// JSON-serializable arguments.
+ /// An instance of obtained by JSON-deserializing the return value.
+ public static ValueTask FastInvoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, TimeSpan timeout, params object?[]? args)
+ {
+ using var cancellationTokenSource = timeout == Timeout.InfiniteTimeSpan ? null : new CancellationTokenSource(timeout);
+ var cancellationToken = cancellationTokenSource?.Token ?? CancellationToken.None;
+
+ return FastInvoke(jsRuntime, identifier, cancellationToken, args);
+ }
+
+ ///
+ /// Invokes the specified JavaScript function with the fastest speed possible.
+ /// Note: In Blazor WebAssembly mode, use this method only for synchronous JavaScript functions.
+ ///
+ /// The JSON-serializable return type.
+ /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction.
+ ///
+ /// A cancellation token to signal the cancellation of the operation. Specifying this parameter will override any default cancellations such as due to timeouts
+ /// () from being applied.
+ ///
+ /// JSON-serializable arguments.
+ /// An instance of obtained by JSON-deserializing the return value.
+ public static ValueTask FastInvoke<[DynamicallyAccessedMembers(JsonSerialized)] TValue>(this IJSRuntime jsRuntime, string identifier, CancellationToken cancellationToken, params object?[]? args)
+ {
+ if (jsRuntime is IJSInProcessRuntime jsInProcessRuntime)
+ {
+ try
+ {
+ return ValueTask.FromResult(jsInProcessRuntime.Invoke(identifier, args));
+ }
+ catch (JsonException ex)
+ {
+ System.Console.Error.WriteLine($"Error invoking '{identifier}' using {nameof(IJSInProcessRuntime)}. A JSON-related issue occurred: {ex.Message}.");
+ return ValueTask.FromResult(default(TValue)!);
+ }
+ }
+ else
+ {
+ return jsRuntime.Invoke(identifier, cancellationToken, args);
+ }
+ }
+}
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj
index e7b299b47d..269fd248cc 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Bit.BlazorUI.Demo.Server.csproj
@@ -1,4 +1,4 @@
-
+net9.0
@@ -13,6 +13,7 @@
allruntime; build; native; contentfiles; analyzers; buildtransitive
+
@@ -49,4 +50,10 @@
+
+
+ PreserveNewest
+
+
+
diff --git a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor
index e2d145bb2d..0bef6e26a6 100644
--- a/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor
+++ b/src/BlazorUI/Demo/Bit.BlazorUI.Demo.Server/Components/App.razor
@@ -46,14 +46,18 @@
@if (HttpContext.Request.IsLightHouseRequest() is false)
{
-
-
-
+ if (AppRenderMode.PrerenderEnabled)
+ {
+
+ }
+
+
+
-
-
-
-
+
+
+
+
}