diff --git a/.github/workflows/label-with-ai.yml b/.github/workflows/label-with-ai.yml
new file mode 100644
index 0000000000..9e2f7ef733
--- /dev/null
+++ b/.github/workflows/label-with-ai.yml
@@ -0,0 +1,36 @@
+name: Apply labels using AI
+
+on:
+ issues:
+ types: [opened, reopened]
+
+jobs:
+ apply-label-and-add-comment:
+ runs-on: ubuntu-latest
+ permissions:
+ issues: write
+ steps:
+ - uses: mattleibow/labeled-by-ai@main
+ name: Apply AREA labels
+ with:
+ label-pattern: '^area/.*'
+ apply-label: 'false'
+ add-comment: 'false'
+ - uses: mattleibow/labeled-by-ai@main
+ name: Apply PLATFORM labels
+ with:
+ label-pattern: '^os/.*'
+ apply-label: 'false'
+ add-comment: 'false'
+ - uses: mattleibow/labeled-by-ai@main
+ name: Apply BACKEND labels
+ with:
+ label-pattern: '^backend/.*'
+ apply-label: 'false'
+ add-comment: 'false'
+ - uses: mattleibow/labeled-by-ai@main
+ name: Apply TENET labels
+ with:
+ label-pattern: '^tenet/.*'
+ apply-label: 'false'
+ add-comment: 'false'
diff --git a/README.md b/README.md
index 52fa4c9396..60cf60052b 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,15 @@ However, these are easy to install as they are found on the various websites. If
- To get started building, [go here](https://github.com/mono/SkiaSharp/wiki/Building-SkiaSharp).
- If you are just wanting a custom Linux build, [go here](https://github.com/mono/SkiaSharp/wiki/Building-on-Linux)
+## Contributors
+
+
+
+
+
+
+Made with [contrib.rocks](https://contrib.rocks).
+
## Compare Code
Here are some links to show the differences in our code as compared to Google's code.
diff --git a/scripts/azure-pipelines-complete-internal.yml b/scripts/azure-pipelines-complete-internal.yml
index 2b8d263e6b..bb66718e6e 100644
--- a/scripts/azure-pipelines-complete-internal.yml
+++ b/scripts/azure-pipelines-complete-internal.yml
@@ -45,7 +45,7 @@ parameters:
default:
pool:
name: Azure Pipelines
- vmImage: macos-13
+ vmImage: macos-14
os: macos
- name: buildAgentLinux
displayName: 'The Linux build agent configuration:'
@@ -144,7 +144,7 @@ extends:
buildAgentWindows: ${{ parameters.buildAgentWindows }}
buildAgentWindowsNative: ${{ parameters.buildAgentWindows }}
buildAgentMac: ${{ parameters.buildAgentMac }}
- buildAgentMacNative: ${{ parameters.buildAgentMac }}
+ buildAgentMacNative: ${{ parameters.buildAgentMacNative }}
buildAgentLinux: ${{ parameters.buildAgentLinux }}
buildAgentLinuxNative: ${{ parameters.buildAgentLinuxNative }}
buildAgentAndroidTests: ${{ parameters.buildAgentAndroidTests }}
diff --git a/scripts/azure-pipelines-complete.yml b/scripts/azure-pipelines-complete.yml
index 25a7b356c1..f2be8f566f 100644
--- a/scripts/azure-pipelines-complete.yml
+++ b/scripts/azure-pipelines-complete.yml
@@ -51,7 +51,7 @@ parameters:
default:
pool:
name: Azure Pipelines
- vmImage: macos-13
+ vmImage: macos-14
os: macos
- name: buildAgentLinux
displayName: 'The Linux build agent configuration:'
diff --git a/scripts/azure-pipelines-variables.yml b/scripts/azure-pipelines-variables.yml
index 754b7dc087..f268685191 100644
--- a/scripts/azure-pipelines-variables.yml
+++ b/scripts/azure-pipelines-variables.yml
@@ -13,7 +13,7 @@ variables:
TIZEN_LINUX_PACKAGES: libxcb-icccm4 libxcb-render-util0 gettext libxcb-image0 libsdl1.2debian libv4l-0 libxcb-randr0 bridge-utils libxcb-shape0 libpython2.7 openvpn libkf5itemmodels5 libkf5kiowidgets5 libkchart2
MANAGED_LINUX_PACKAGES: ttf-ancient-fonts ninja-build
XCODE_VERSION: '15.4'
- XCODE_VERSION_NATIVE: '14.3.1'
+ XCODE_VERSION_NATIVE: '15.4'
VISUAL_STUDIO_VERSION: ''
DOTNET_VERSION: '8.0.304'
DOTNET_VERSION_PREVIEW: ''
diff --git a/scripts/azure-pipelines.yml b/scripts/azure-pipelines.yml
index 65e618fc50..f37d76ee8a 100644
--- a/scripts/azure-pipelines.yml
+++ b/scripts/azure-pipelines.yml
@@ -51,7 +51,7 @@ parameters:
default:
pool:
name: Azure Pipelines
- vmImage: macos-13
+ vmImage: macos-14
os: macos
- name: buildAgentLinux
displayName: 'The Linux build agent configuration:'
diff --git a/scripts/azure-templates-bootstrapper.yml b/scripts/azure-templates-bootstrapper.yml
index 54f677c4ba..6f0c90b899 100644
--- a/scripts/azure-templates-bootstrapper.yml
+++ b/scripts/azure-templates-bootstrapper.yml
@@ -87,10 +87,10 @@ jobs:
submodules: recursive
- template: /scripts/azure-templates-variables.yml@self
- # checkout required skia PR
- - pwsh: .\scripts\checkout-skia.ps1 -GitHubToken $(GitHub.Token.PublicAccess)
- displayName: Checkout required skia PR
- condition: eq(variables['Build.Reason'], 'PullRequest')
+ # # checkout required skia PR
+ # - pwsh: .\scripts\checkout-skia.ps1 -GitHubToken $(GitHub.Token.PublicAccess)
+ # displayName: Checkout required skia PR
+ # condition: eq(variables['Build.Reason'], 'PullRequest')
- ${{ if eq(parameters.buildPipelineType, 'tests') }}:
- template: /scripts/azure-templates-github-status.yml@self
diff --git a/scripts/azure-templates-stages.yml b/scripts/azure-templates-stages.yml
index 97ef62373b..ff126e8d78 100644
--- a/scripts/azure-templates-stages.yml
+++ b/scripts/azure-templates-stages.yml
@@ -458,11 +458,11 @@ stages:
- 3.1.56:
displayName: '3.1.56_SIMD'
version: 3.1.56
- features: _wasmeh,simd,st
+ features: _wasmeh,st,simd
- 3.1.56:
displayName: '3.1.56_SIMD_Threading'
version: 3.1.56
- features: _wasmeh,simd,mt
+ features: _wasmeh,mt,simd
- ${{ if ne(parameters.buildPipelineType, 'tests') }}:
- stage: native
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/ActionHelper.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/ActionHelper.cs
index 29a39cf0f6..c9c705de28 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/ActionHelper.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/ActionHelper.cs
@@ -1,4 +1,5 @@
-using System;
+#if !NET7_0_OR_GREATER
+using System;
using System.ComponentModel;
using Microsoft.JSInterop;
@@ -18,3 +19,4 @@ public ActionHelper(Action action)
public void Invoke() => action?.Invoke();
}
}
+#endif
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/DpiWatcherInterop.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/DpiWatcherInterop.cs
index 80223f31fa..a5553c01df 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/DpiWatcherInterop.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/DpiWatcherInterop.cs
@@ -1,11 +1,18 @@
-using System;
+using System;
+using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.JSInterop;
+#if NET7_0_OR_GREATER
+using System.Runtime.InteropServices.JavaScript;
+#endif
+
namespace SkiaSharp.Views.Blazor.Internal
{
- internal class DpiWatcherInterop : JSModuleInterop
+ [SupportedOSPlatform("browser")]
+ internal partial class DpiWatcherInterop : JSModuleInterop
{
+ private const string ModuleName = "DpiWatcher";
private const string JsFilename = "./_content/SkiaSharp.Views.Blazor/DpiWatcher.js";
private const string StartSymbol = "DpiWatcher.start";
private const string StopSymbol = "DpiWatcher.stop";
@@ -14,9 +21,13 @@ internal class DpiWatcherInterop : JSModuleInterop
private static DpiWatcherInterop? instance;
private event Action? callbacksEvent;
+#if NET7_0_OR_GREATER
+ private readonly Action callbackHelper;
+#else
private readonly FloatFloatActionHelper callbackHelper;
private DotNetObjectReference? callbackReference;
+#endif
public static async Task ImportAsync(IJSRuntime js, Action? callback = null)
{
@@ -31,9 +42,9 @@ public static DpiWatcherInterop Get(IJSRuntime js) =>
instance ??= new DpiWatcherInterop(js);
private DpiWatcherInterop(IJSRuntime js)
- : base(js, JsFilename)
+ : base(js, ModuleName, JsFilename)
{
- callbackHelper = new FloatFloatActionHelper((o, n) => callbacksEvent?.Invoke(n));
+ callbackHelper = new((o, n) => callbacksEvent?.Invoke((float)n));
}
protected override void OnDisposingModule() =>
@@ -60,21 +71,28 @@ public void Unsubscribe(Action callback)
Stop();
}
+#if NET7_0_OR_GREATER
+ private double Start() =>
+ Start(callbackHelper);
+
+ [JSImport(StartSymbol, ModuleName)]
+ private static partial double Start([JSMarshalAs>] Action callback);
+
+ [JSImport(StopSymbol, ModuleName)]
+ private static partial void Stop();
+
+ [JSImport(GetDpiSymbol, ModuleName)]
+ public static partial double GetDpi();
+#else
private double Start()
{
- if (callbackReference != null)
- return GetDpi();
-
- callbackReference = DotNetObjectReference.Create(callbackHelper);
+ callbackReference ??= DotNetObjectReference.Create(callbackHelper);
return Invoke(StartSymbol, callbackReference);
}
private void Stop()
{
- if (callbackReference == null)
- return;
-
Invoke(StopSymbol);
callbackReference?.Dispose();
@@ -83,5 +101,6 @@ private void Stop()
public double GetDpi() =>
Invoke(GetDpiSymbol);
+#endif
}
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/FloatFloatActionHelper.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/FloatFloatActionHelper.cs
index d8b5b4b4f5..b88056e93b 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/FloatFloatActionHelper.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/FloatFloatActionHelper.cs
@@ -1,4 +1,5 @@
-using System;
+#if !NET7_0_OR_GREATER
+using System;
using System.ComponentModel;
using Microsoft.JSInterop;
@@ -18,3 +19,4 @@ public FloatFloatActionHelper(Action action)
public void Invoke(float width, float height) => action?.Invoke(width, height);
}
}
+#endif
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/JSModuleInterop.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/JSModuleInterop.cs
index de42afa15b..6acc23d2e3 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/JSModuleInterop.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/JSModuleInterop.cs
@@ -1,20 +1,32 @@
using System;
using System.Threading.Tasks;
+using System.Runtime.Versioning;
using Microsoft.JSInterop;
+#if NET7_0_OR_GREATER
+using System.Runtime.InteropServices.JavaScript;
+#else
+using JSObject = Microsoft.JSInterop.IJSUnmarshalledObjectReference;
+#endif
+
namespace SkiaSharp.Views.Blazor.Internal
{
- internal class JSModuleInterop : IDisposable
+ [SupportedOSPlatform("browser")]
+ internal partial class JSModuleInterop : IDisposable
{
- private readonly Task moduleTask;
- private IJSUnmarshalledObjectReference? module;
+ private readonly Task moduleTask;
+ private JSObject? module;
- public JSModuleInterop(IJSRuntime js, string filename)
+ public JSModuleInterop(IJSRuntime js, string moduleName, string moduleUrl)
{
+#if NET7_0_OR_GREATER
+ moduleTask = JSHost.ImportAsync(moduleName, "/" + moduleUrl);
+#else
if (js is not IJSInProcessRuntime)
throw new NotSupportedException("SkiaSharp currently only works on Web Assembly.");
- moduleTask = js.InvokeAsync("import", filename).AsTask();
+ moduleTask = js.InvokeAsync("import", moduleUrl).AsTask();
+#endif
}
public async Task ImportAsync()
@@ -28,14 +40,16 @@ public void Dispose()
Module.Dispose();
}
- protected IJSUnmarshalledObjectReference Module =>
+ protected JSObject Module =>
module ?? throw new InvalidOperationException("Make sure to run ImportAsync() first.");
+#if !NET7_0_OR_GREATER
protected void Invoke(string identifier, params object?[]? args) =>
Module.InvokeVoid(identifier, args);
protected TValue Invoke(string identifier, params object?[]? args) =>
Module.Invoke(identifier, args);
+#endif
protected virtual void OnDisposingModule() { }
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SKHtmlCanvasInterop.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SKHtmlCanvasInterop.cs
index 29cbfac86f..31d48dc58b 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SKHtmlCanvasInterop.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SKHtmlCanvasInterop.cs
@@ -1,13 +1,20 @@
using System;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
+#if NET7_0_OR_GREATER
+using System.Runtime.InteropServices.JavaScript;
+#endif
+
namespace SkiaSharp.Views.Blazor.Internal
{
- internal class SKHtmlCanvasInterop : JSModuleInterop
+ [SupportedOSPlatform("browser")]
+ internal partial class SKHtmlCanvasInterop : JSModuleInterop
{
+ private const string ModuleName = "SKHtmlCanvas";
private const string JsFilename = "./_content/SkiaSharp.Views.Blazor/SKHtmlCanvas.js";
private const string InitGLSymbol = "SKHtmlCanvas.initGL";
private const string InitRasterSymbol = "SKHtmlCanvas.initRaster";
@@ -17,9 +24,13 @@ internal class SKHtmlCanvasInterop : JSModuleInterop
private readonly ElementReference htmlCanvas;
private readonly string htmlElementId;
+#if NET7_0_OR_GREATER
+ private readonly Action callbackHelper;
+#else
private readonly ActionHelper callbackHelper;
private DotNetObjectReference? callbackReference;
+#endif
public static async Task ImportAsync(IJSRuntime js, ElementReference element, Action callback)
{
@@ -29,30 +40,69 @@ public static async Task ImportAsync(IJSRuntime js, Element
}
public SKHtmlCanvasInterop(IJSRuntime js, ElementReference element, Action renderFrameCallback)
- : base(js, JsFilename)
+ : base(js, ModuleName, JsFilename)
{
htmlCanvas = element;
- htmlElementId = element.Id;
+ htmlElementId = "_bl_" + element.Id;
- callbackHelper = new ActionHelper(renderFrameCallback);
+ callbackHelper = new(renderFrameCallback);
}
protected override void OnDisposingModule() =>
Deinit();
+#if NET7_0_OR_GREATER
+ public GLInfo InitGL()
+ {
+ Init();
+
+ var obj = InitGL(null, htmlElementId, callbackHelper);
+ var info = new GLInfo(
+ obj.GetPropertyAsInt32("contextId"),
+ (uint)obj.GetPropertyAsInt32("fboId"),
+ obj.GetPropertyAsInt32("stencils"),
+ obj.GetPropertyAsInt32("samples"),
+ obj.GetPropertyAsInt32("depth"));
+ return info;
+ }
+
+ [JSImport(InitGLSymbol, ModuleName)]
+ public static partial JSObject InitGL(JSObject? element, string elementId, [JSMarshalAs] Action callback);
+
+ public bool InitRaster()
+ {
+ Init();
+
+ return InitRaster(null, htmlElementId, callbackHelper);
+ }
+
+ [JSImport(InitRasterSymbol, ModuleName)]
+ public static partial bool InitRaster(JSObject? element, string elementId, [JSMarshalAs] Action callback);
+
+ public void Deinit() =>
+ Deinit(htmlElementId);
+
+ [JSImport(DeinitSymbol, ModuleName)]
+ public static partial void Deinit(string elementId);
+
+ public void RequestAnimationFrame(bool enableRenderLoop, int rawWidth, int rawHeight) =>
+ RequestAnimationFrame(htmlElementId, enableRenderLoop, rawWidth, rawHeight);
+
+ [JSImport(RequestAnimationFrameSymbol, ModuleName)]
+ public static partial void RequestAnimationFrame(string elementId, bool enableRenderLoop, int rawWidth, int rawHeight);
+
+ public void PutImageData(IntPtr intPtr, SKSizeI rawSize) =>
+ PutImageData(htmlElementId, intPtr, rawSize.Width, rawSize.Height);
+
+ [JSImport(PutImageDataSymbol, ModuleName)]
+ public static partial void PutImageData(string elementId, IntPtr intPtr, int rawWidth, int rawHeight);
+#else
public GLInfo InitGL()
{
if (callbackReference != null)
throw new InvalidOperationException("Unable to initialize the same canvas more than once.");
- try
- {
- InterceptGLObject();
- }
- catch
- {
- // no-op
- }
+ Init();
callbackReference = DotNetObjectReference.Create(callbackHelper);
@@ -64,6 +114,8 @@ public bool InitRaster()
if (callbackReference != null)
throw new InvalidOperationException("Unable to initialize the same canvas more than once.");
+ Init();
+
callbackReference = DotNetObjectReference.Create(callbackHelper);
return Invoke(InitRasterSymbol, htmlCanvas, htmlElementId, callbackReference);
@@ -80,15 +132,28 @@ public void Deinit()
}
public void RequestAnimationFrame(bool enableRenderLoop, int rawWidth, int rawHeight) =>
- Invoke(RequestAnimationFrameSymbol, htmlCanvas, enableRenderLoop, rawWidth, rawHeight);
+ Invoke(RequestAnimationFrameSymbol, htmlElementId, enableRenderLoop, rawWidth, rawHeight);
public void PutImageData(IntPtr intPtr, SKSizeI rawSize) =>
- Invoke(PutImageDataSymbol, htmlCanvas, intPtr.ToInt64(), rawSize.Width, rawSize.Height);
+ Invoke(PutImageDataSymbol, htmlElementId, intPtr.ToInt64(), rawSize.Width, rawSize.Height);
+#endif
public record GLInfo(int ContextId, uint FboId, int Stencils, int Samples, int Depth);
+ static void Init()
+ {
+ try
+ {
+ InterceptBrowserObjects();
+ }
+ catch
+ {
+ // no-op
+ }
+ }
+
// Workaround for https://github.com/dotnet/runtime/issues/76077
[DllImport("libSkiaSharp", CallingConvention = CallingConvention.Cdecl)]
- static extern void InterceptGLObject();
+ static extern void InterceptBrowserObjects();
}
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SizeWatcherInterop.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SizeWatcherInterop.cs
index fb82809890..f37e9fdc01 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SizeWatcherInterop.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/Internal/SizeWatcherInterop.cs
@@ -1,21 +1,32 @@
using System;
+using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
+#if NET7_0_OR_GREATER
+using System.Runtime.InteropServices.JavaScript;
+#endif
+
namespace SkiaSharp.Views.Blazor.Internal
{
- internal class SizeWatcherInterop : JSModuleInterop
+ [SupportedOSPlatform("browser")]
+ internal partial class SizeWatcherInterop : JSModuleInterop
{
+ private const string ModuleName = "SizeWatcher";
private const string JsFilename = "./_content/SkiaSharp.Views.Blazor/SizeWatcher.js";
private const string ObserveSymbol = "SizeWatcher.observe";
private const string UnobserveSymbol = "SizeWatcher.unobserve";
private readonly ElementReference htmlElement;
private readonly string htmlElementId;
+#if NET7_0_OR_GREATER
+ private readonly Action callbackHelper;
+#else
private readonly FloatFloatActionHelper callbackHelper;
private DotNetObjectReference? callbackReference;
+#endif
public static async Task ImportAsync(IJSRuntime js, ElementReference element, Action callback)
{
@@ -26,22 +37,32 @@ public static async Task ImportAsync(IJSRuntime js, ElementR
}
public SizeWatcherInterop(IJSRuntime js, ElementReference element, Action callback)
- : base(js, JsFilename)
+ : base(js, ModuleName, JsFilename)
{
htmlElement = element;
- htmlElementId = element.Id;
- callbackHelper = new FloatFloatActionHelper((x, y) => callback(new SKSize(x, y)));
+ htmlElementId = "_bl_" + element.Id;
+ callbackHelper = new((x, y) => callback(new SKSize(x, y)));
}
protected override void OnDisposingModule() =>
Stop();
+#if NET7_0_OR_GREATER
+ public void Start() =>
+ Observe(null, htmlElementId, callbackHelper);
+
+ public void Stop() =>
+ Unobserve(htmlElementId);
+
+ [JSImport(ObserveSymbol, ModuleName)]
+ private static partial void Observe(JSObject? element, string elementId, [JSMarshalAs>] Action callback);
+
+ [JSImport(UnobserveSymbol, ModuleName)]
+ private static partial void Unobserve(string elementId);
+#else
public void Start()
{
- if (callbackReference != null)
- return;
-
- callbackReference = DotNetObjectReference.Create(callbackHelper);
+ callbackReference ??= DotNetObjectReference.Create(callbackHelper);
Invoke(ObserveSymbol, htmlElement, htmlElementId, callbackReference);
}
@@ -56,5 +77,6 @@ public void Stop()
callbackReference?.Dispose();
callbackReference = null;
}
+#endif
}
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs
index 7d803f3496..388ccc94d0 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKCanvasView.razor.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
@@ -8,6 +9,7 @@
namespace SkiaSharp.Views.Blazor
{
+ [SupportedOSPlatform("browser")]
public partial class SKCanvasView : IDisposable
{
private SKHtmlCanvasInterop interop = null!;
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs
index 6473fb1e8e..fdf68d18d2 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SKGLView.razor.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
@@ -7,6 +8,7 @@
namespace SkiaSharp.Views.Blazor
{
+ [SupportedOSPlatform("browser")]
public partial class SKGLView : IDisposable
{
private SKHtmlCanvasInterop interop = null!;
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SkiaSharp.Views.Blazor.csproj b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SkiaSharp.Views.Blazor.csproj
index 8ce803a54f..3c20e1bfb8 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SkiaSharp.Views.Blazor.csproj
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/SkiaSharp.Views.Blazor.csproj
@@ -20,6 +20,7 @@
+
@@ -37,7 +38,7 @@
-
+
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.Local.props b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.Local.props
index bf5939b8be..0e0d66dbf9 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.Local.props
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.Local.props
@@ -3,7 +3,25 @@
- $(EmccExtraLDFlags) --js-library="$(MSBuildThisFileDirectory)SkiaSharpGLInterop.js"
+ $(EmccExtraLDFlags) --js-library="$(MSBuildThisFileDirectory)SkiaSharpInterop.js"
+
+
+
+ <_WasmLinkStepArgs Remove="@(_EmccLinkStepArgs)" />
+ <_EmccLinkStepArgs Remove=""%(_WasmNativeFileForLinking.Identity)"" />
+ <_WasmLinkDependencies Remove="@(_WasmNativeFileForLinking)" />
+
+ <_SkiaSharpToReorder Include="@(_WasmNativeFileForLinking)" Condition="$([System.String]::Copy('%(FullPath)').Contains('libSkiaSharp.a'))" />
+ <_WasmNativeFileForLinking Remove="@(_SkiaSharpToReorder)" />
+ <_WasmNativeFileForLinking Include="@(_SkiaSharpToReorder)" />
+
+ <_EmccLinkStepArgs Include=""%(_WasmNativeFileForLinking.Identity)"" />
+ <_WasmLinkDependencies Include="@(_WasmNativeFileForLinking)" />
+ <_WasmLinkStepArgs Include="@(_EmccLinkStepArgs)" />
+
+
+
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.props b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.props
index d4dd8e8544..ba56e78057 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.props
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharp.Views.Blazor.props
@@ -3,9 +3,27 @@
- $(EmccExtraLDFlags) --js-library="$(MSBuildThisFileDirectory)\SkiaSharpGLInterop.js"
+ $(EmccExtraLDFlags) --js-library="$(MSBuildThisFileDirectory)SkiaSharpInterop.js"
+
+
+
+ <_WasmLinkStepArgs Remove="@(_EmccLinkStepArgs)" />
+ <_EmccLinkStepArgs Remove=""%(_WasmNativeFileForLinking.Identity)"" />
+ <_WasmLinkDependencies Remove="@(_WasmNativeFileForLinking)" />
+
+ <_SkiaSharpToReorder Include="@(_WasmNativeFileForLinking)" Condition="$([System.String]::Copy('%(FullPath)').Contains('libSkiaSharp.a'))" />
+ <_WasmNativeFileForLinking Remove="@(_SkiaSharpToReorder)" />
+ <_WasmNativeFileForLinking Include="@(_SkiaSharpToReorder)" />
+
+ <_EmccLinkStepArgs Include=""%(_WasmNativeFileForLinking.Identity)"" />
+ <_WasmLinkDependencies Include="@(_WasmNativeFileForLinking)" />
+ <_WasmLinkStepArgs Include="@(_EmccLinkStepArgs)" />
+
+
+
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharpGLInterop.js b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharpGLInterop.js
deleted file mode 100644
index 24d24d659d..0000000000
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharpGLInterop.js
+++ /dev/null
@@ -1,15 +0,0 @@
-// Workaround for https://github.com/dotnet/runtime/issues/76077
-// Special thanks to the Avalonia UI team
-
-var SkiaSharpGLInterop = {
- $SkiaSharpLibrary: {
- internal_func: function () {
- }
- },
- InterceptGLObject: function () {
- globalThis.SkiaSharpGL = GL
- }
-}
-
-autoAddDeps(SkiaSharpGLInterop, '$SkiaSharpLibrary')
-mergeInto(LibraryManager.library, SkiaSharpGLInterop)
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharpInterop.js b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharpInterop.js
new file mode 100644
index 0000000000..67568ba718
--- /dev/null
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/nuget/buildTransitive/SkiaSharpInterop.js
@@ -0,0 +1,16 @@
+// Workaround for https://github.com/dotnet/runtime/issues/76077
+// Special thanks to the Avalonia UI team
+
+var SkiaSharpInterop = {
+ $SkiaSharpLibrary: {
+ internal_func: function () {
+ }
+ },
+ InterceptBrowserObjects: function () {
+ globalThis.SkiaSharpGL = GL
+ globalThis.SkiaSharpModule = Module
+ }
+}
+
+autoAddDeps(SkiaSharpInterop, '$SkiaSharpLibrary')
+mergeInto(LibraryManager.library, SkiaSharpInterop)
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.js b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.js
index f0a32d704b..635cd40c90 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.js
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.js
@@ -21,7 +21,12 @@ export class DpiWatcher {
const lastDpi = DpiWatcher.lastDpi;
DpiWatcher.lastDpi = currentDpi;
if (Math.abs(lastDpi - currentDpi) > 0.001) {
- DpiWatcher.callback.invokeMethod('Invoke', lastDpi, currentDpi);
+ if (typeof DpiWatcher.callback === 'function') {
+ DpiWatcher.callback(lastDpi, currentDpi);
+ }
+ else {
+ DpiWatcher.callback.invokeMethod('Invoke', lastDpi, currentDpi);
+ }
}
}
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.ts b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.ts
index 72baf14d8f..a0922abdd5 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.ts
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/DpiWatcher.ts
@@ -1,14 +1,16 @@
+type DpiWatcherCallback = DotNet.DotNetObjectReference | ((lastDpi: number, currentDpi: number) => void);
+
export class DpiWatcher {
static lastDpi: number;
static timerId: number;
- static callback: DotNet.DotNetObjectReference;
+ static callback: DpiWatcherCallback;
public static getDpi() {
return window.devicePixelRatio;
}
- public static start(callback: DotNet.DotNetObjectReference): number {
+ public static start(callback: DpiWatcherCallback): number {
//console.info(`Starting DPI watcher with callback ${callback._id}...`);
DpiWatcher.lastDpi = window.devicePixelRatio;
@@ -35,7 +37,11 @@ export class DpiWatcher {
DpiWatcher.lastDpi = currentDpi;
if (Math.abs(lastDpi - currentDpi) > 0.001) {
- DpiWatcher.callback.invokeMethod('Invoke', lastDpi, currentDpi);
+ if (typeof DpiWatcher.callback === 'function') {
+ DpiWatcher.callback(lastDpi, currentDpi);
+ } else {
+ DpiWatcher.callback.invokeMethod('Invoke', lastDpi, currentDpi);
+ }
}
}
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.js b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.js
index 3264a9228c..d0907933bd 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.js
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.js
@@ -12,6 +12,7 @@ export class SKHtmlCanvas {
return true;
}
static init(useGL, element, elementId, callback) {
+ element = element || document.querySelector('[' + elementId + ']');
var htmlCanvas = element;
if (!htmlCanvas) {
console.error(`No canvas element was provided.`);
@@ -19,7 +20,7 @@ export class SKHtmlCanvas {
}
if (!SKHtmlCanvas.elements)
SKHtmlCanvas.elements = new Map();
- SKHtmlCanvas.elements[elementId] = element;
+ SKHtmlCanvas.elements.set(elementId, element);
const view = new SKHtmlCanvas(useGL, element, callback);
htmlCanvas.SKHtmlCanvas = view;
return view;
@@ -27,28 +28,28 @@ export class SKHtmlCanvas {
static deinit(elementId) {
if (!elementId)
return;
- const element = SKHtmlCanvas.elements[elementId];
- SKHtmlCanvas.elements.delete(elementId);
+ const element = SKHtmlCanvas.elements.get(elementId);
+ const removed = SKHtmlCanvas.elements.delete(elementId);
const htmlCanvas = element;
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.deinit();
htmlCanvas.SKHtmlCanvas = undefined;
}
- static requestAnimationFrame(element, renderLoop, width, height) {
- const htmlCanvas = element;
+ static requestAnimationFrame(elementId, renderLoop, width, height) {
+ const htmlCanvas = SKHtmlCanvas.elements.get(elementId);
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.requestAnimationFrame(renderLoop, width, height);
}
- static setEnableRenderLoop(element, enable) {
- const htmlCanvas = element;
+ static setEnableRenderLoop(elementId, enable) {
+ const htmlCanvas = SKHtmlCanvas.elements.get(elementId);
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.setEnableRenderLoop(enable);
}
- static putImageData(element, pData, width, height) {
- const htmlCanvas = element;
+ static putImageData(elementId, pData, width, height) {
+ const htmlCanvas = SKHtmlCanvas.elements.get(elementId);
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.putImageData(pData, width, height);
@@ -101,7 +102,12 @@ export class SKHtmlCanvas {
const GL = SKHtmlCanvas.getGL();
GL.makeContextCurrent(this.glInfo.context);
}
- this.renderFrameCallback.invokeMethod('Invoke');
+ if (typeof this.renderFrameCallback === 'function') {
+ this.renderFrameCallback();
+ }
+ else {
+ this.renderFrameCallback.invokeMethod('Invoke');
+ }
this.renderLoopRequest = 0;
// we may want to draw the next frame
if (this.renderLoopEnabled)
@@ -132,6 +138,7 @@ export class SKHtmlCanvas {
this.htmlCanvas.width = width;
this.htmlCanvas.height = height;
// set the canvas to be the bytes
+ const Module = SKHtmlCanvas.getModule();
var buffer = new Uint8ClampedArray(Module.HEAPU8.buffer, pData, width * height * 4);
var imageData = new ImageData(buffer, width, height);
ctx.putImageData(imageData, 0, 0);
@@ -166,6 +173,9 @@ export class SKHtmlCanvas {
static getGL() {
return globalThis.SkiaSharpGL || Module.GL || GL;
}
+ static getModule() {
+ return globalThis.SkiaSharpModule || Module;
+ }
static getGLctx() {
const GL = SKHtmlCanvas.getGL();
return GL.currentContext && GL.currentContext.GLctx || GLctx;
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.ts b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.ts
index 45605d9e83..5f18ae3843 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.ts
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SKHtmlCanvas.ts
@@ -17,16 +17,18 @@ type SKHtmlCanvasElement = {
SKHtmlCanvas: SKHtmlCanvas
} & HTMLCanvasElement
+type SKHtmlCanvasCallback = DotNet.DotNetObjectReference | (() => void);
+
export class SKHtmlCanvas {
static elements: Map;
htmlCanvas: HTMLCanvasElement;
glInfo: SKGLViewInfo;
- renderFrameCallback: DotNet.DotNetObjectReference;
+ renderFrameCallback: SKHtmlCanvasCallback;
renderLoopEnabled: boolean = false;
renderLoopRequest: number = 0;
- public static initGL(element: HTMLCanvasElement, elementId: string, callback: DotNet.DotNetObjectReference): SKGLViewInfo {
+ public static initGL(element: HTMLCanvasElement, elementId: string, callback: SKHtmlCanvasCallback): SKGLViewInfo {
var view = SKHtmlCanvas.init(true, element, elementId, callback);
if (!view || !view.glInfo)
return null;
@@ -34,7 +36,7 @@ export class SKHtmlCanvas {
return view.glInfo;
}
- public static initRaster(element: HTMLCanvasElement, elementId: string, callback: DotNet.DotNetObjectReference): boolean {
+ public static initRaster(element: HTMLCanvasElement, elementId: string, callback: SKHtmlCanvasCallback): boolean {
var view = SKHtmlCanvas.init(false, element, elementId, callback);
if (!view)
return false;
@@ -42,7 +44,8 @@ export class SKHtmlCanvas {
return true;
}
- static init(useGL: boolean, element: HTMLCanvasElement, elementId: string, callback: DotNet.DotNetObjectReference): SKHtmlCanvas {
+ static init(useGL: boolean, element: HTMLCanvasElement, elementId: string, callback: SKHtmlCanvasCallback): SKHtmlCanvas {
+ element = element || document.querySelector('[' + elementId + ']');
var htmlCanvas = element as SKHtmlCanvasElement;
if (!htmlCanvas) {
console.error(`No canvas element was provided.`);
@@ -51,7 +54,7 @@ export class SKHtmlCanvas {
if (!SKHtmlCanvas.elements)
SKHtmlCanvas.elements = new Map();
- SKHtmlCanvas.elements[elementId] = element;
+ SKHtmlCanvas.elements.set(elementId, element);
const view = new SKHtmlCanvas(useGL, element, callback);
@@ -64,8 +67,8 @@ export class SKHtmlCanvas {
if (!elementId)
return;
- const element = SKHtmlCanvas.elements[elementId];
- SKHtmlCanvas.elements.delete(elementId);
+ const element = SKHtmlCanvas.elements.get(elementId);
+ const removed = SKHtmlCanvas.elements.delete(elementId);
const htmlCanvas = element as SKHtmlCanvasElement;
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
@@ -75,31 +78,31 @@ export class SKHtmlCanvas {
htmlCanvas.SKHtmlCanvas = undefined;
}
- public static requestAnimationFrame(element: HTMLCanvasElement, renderLoop?: boolean, width?: number, height?: number) {
- const htmlCanvas = element as SKHtmlCanvasElement;
+ public static requestAnimationFrame(elementId: string, renderLoop?: boolean, width?: number, height?: number) {
+ const htmlCanvas = SKHtmlCanvas.elements.get(elementId) as SKHtmlCanvasElement;
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.requestAnimationFrame(renderLoop, width, height);
}
- public static setEnableRenderLoop(element: HTMLCanvasElement, enable: boolean) {
- const htmlCanvas = element as SKHtmlCanvasElement;
+ public static setEnableRenderLoop(elementId: string, enable: boolean) {
+ const htmlCanvas = SKHtmlCanvas.elements.get(elementId) as SKHtmlCanvasElement;
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.setEnableRenderLoop(enable);
}
- public static putImageData(element: HTMLCanvasElement, pData: number, width: number, height: number) {
- const htmlCanvas = element as SKHtmlCanvasElement;
+ public static putImageData(elementId: string, pData: number, width: number, height: number) {
+ const htmlCanvas = SKHtmlCanvas.elements.get(elementId) as SKHtmlCanvasElement;
if (!htmlCanvas || !htmlCanvas.SKHtmlCanvas)
return;
htmlCanvas.SKHtmlCanvas.putImageData(pData, width, height);
}
- public constructor(useGL: boolean, element: HTMLCanvasElement, callback: DotNet.DotNetObjectReference) {
+ public constructor(useGL: boolean, element: HTMLCanvasElement, callback: SKHtmlCanvasCallback) {
this.htmlCanvas = element;
this.renderFrameCallback = callback;
@@ -154,7 +157,11 @@ export class SKHtmlCanvas {
GL.makeContextCurrent(this.glInfo.context);
}
- this.renderFrameCallback.invokeMethod('Invoke');
+ if (typeof this.renderFrameCallback === 'function') {
+ this.renderFrameCallback();
+ } else {
+ this.renderFrameCallback.invokeMethod('Invoke');
+ }
this.renderLoopRequest = 0;
// we may want to draw the next frame
@@ -191,6 +198,7 @@ export class SKHtmlCanvas {
this.htmlCanvas.height = height;
// set the canvas to be the bytes
+ const Module = SKHtmlCanvas.getModule();
var buffer = new Uint8ClampedArray(Module.HEAPU8.buffer, pData, width * height * 4);
var imageData = new ImageData(buffer, width, height);
ctx.putImageData(imageData, 0, 0);
@@ -231,6 +239,10 @@ export class SKHtmlCanvas {
return (globalThis as any).SkiaSharpGL || (Module as any).GL || GL;
}
+ static getModule(): EmscriptenModule {
+ return (globalThis as any).SkiaSharpModule || (Module as any);
+ }
+
static getGLctx(): WebGLRenderingContext {
const GL = SKHtmlCanvas.getGL();
return GL.currentContext && GL.currentContext.GLctx || GLctx;
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.js b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.js
index 4809dc7e3b..7c57c394de 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.js
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.js
@@ -1,14 +1,15 @@
export class SizeWatcher {
static observe(element, elementId, callback) {
- if (!element || !callback)
+ if ((!element && !elementId) || !callback)
return;
//console.info(`Adding size watcher observation with callback ${callback._id}...`);
SizeWatcher.init();
+ element = element || document.querySelector('[' + elementId + ']');
const watcherElement = element;
watcherElement.SizeWatcher = {
callback: callback
};
- SizeWatcher.elements[elementId] = element;
+ SizeWatcher.elements.set(elementId, element);
SizeWatcher.observer.observe(element);
SizeWatcher.invoke(element);
}
@@ -16,8 +17,8 @@ export class SizeWatcher {
if (!elementId || !SizeWatcher.observer)
return;
//console.info('Removing size watcher observation...');
- const element = SizeWatcher.elements[elementId];
- SizeWatcher.elements.delete(elementId);
+ const element = SizeWatcher.elements.get(elementId);
+ const removed = SizeWatcher.elements.delete(elementId);
SizeWatcher.observer.unobserve(element);
}
static init() {
@@ -36,6 +37,11 @@ export class SizeWatcher {
const instance = watcherElement.SizeWatcher;
if (!instance || !instance.callback)
return;
- return instance.callback.invokeMethod('Invoke', element.clientWidth, element.clientHeight);
+ if (typeof instance.callback === 'function') {
+ instance.callback(element.clientWidth, element.clientHeight);
+ }
+ else {
+ instance.callback.invokeMethod('Invoke', element.clientWidth, element.clientHeight);
+ }
}
}
diff --git a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.ts b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.ts
index 88b94f3a80..1664bd04c5 100644
--- a/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.ts
+++ b/source/SkiaSharp.Views/SkiaSharp.Views.Blazor/wwwroot/SizeWatcher.ts
@@ -3,28 +3,32 @@ type SizeWatcherElement = {
SizeWatcher: SizeWatcherInstance;
} & HTMLElement
+type SizeWatcherCallback = DotNet.DotNetObjectReference | ((width: number, height: number) => void);
+
type SizeWatcherInstance = {
- callback: DotNet.DotNetObjectReference;
+ callback: SizeWatcherCallback;
}
export class SizeWatcher {
static observer: ResizeObserver;
static elements: Map;
- public static observe(element: HTMLElement, elementId: string, callback: DotNet.DotNetObjectReference) {
- if (!element || !callback)
+ public static observe(element: HTMLElement, elementId: string, callback: SizeWatcherCallback) {
+ if ((!element && !elementId) || !callback)
return;
//console.info(`Adding size watcher observation with callback ${callback._id}...`);
SizeWatcher.init();
+ element = element || document.querySelector('[' + elementId + ']');
+
const watcherElement = element as SizeWatcherElement;
watcherElement.SizeWatcher = {
callback: callback
};
- SizeWatcher.elements[elementId] = element;
+ SizeWatcher.elements.set(elementId, element);
SizeWatcher.observer.observe(element);
SizeWatcher.invoke(element);
@@ -36,9 +40,8 @@ export class SizeWatcher {
//console.info('Removing size watcher observation...');
- const element = SizeWatcher.elements[elementId];
-
- SizeWatcher.elements.delete(elementId);
+ const element = SizeWatcher.elements.get(elementId);
+ const removed = SizeWatcher.elements.delete(elementId);
SizeWatcher.observer.unobserve(element);
}
@@ -63,6 +66,10 @@ export class SizeWatcher {
if (!instance || !instance.callback)
return;
- return instance.callback.invokeMethod('Invoke', element.clientWidth, element.clientHeight);
+ if (typeof instance.callback === 'function') {
+ instance.callback(element.clientWidth, element.clientHeight);
+ } else {
+ instance.callback.invokeMethod('Invoke', element.clientWidth, element.clientHeight);
+ }
}
}