14 changed files with 289 additions and 30 deletions
@ -0,0 +1,91 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Runtime.InteropServices.JavaScript; |
|||
using Avalonia.Browser.Interop; |
|||
using Avalonia.Browser.Storage; |
|||
using Avalonia.Input; |
|||
using Avalonia.Platform.Storage; |
|||
|
|||
namespace Avalonia.Browser; |
|||
|
|||
internal class BrowserDataObject : IDataObject |
|||
{ |
|||
private readonly JSObject _dataObject; |
|||
|
|||
public BrowserDataObject(JSObject dataObject) |
|||
{ |
|||
_dataObject = dataObject; |
|||
} |
|||
|
|||
public IEnumerable<string> GetDataFormats() |
|||
{ |
|||
var types = new HashSet<string>(_dataObject.GetPropertyAsStringArray("types")); |
|||
var dataFormats = new HashSet<string>(types.Count); |
|||
|
|||
foreach (var type in types) |
|||
{ |
|||
if (type.StartsWith("text/", StringComparison.Ordinal)) |
|||
{ |
|||
dataFormats.Add(DataFormats.Text); |
|||
} |
|||
else if (type.Equals("Files", StringComparison.Ordinal)) |
|||
{ |
|||
dataFormats.Add(DataFormats.Files); |
|||
} |
|||
dataFormats.Add(type); |
|||
} |
|||
|
|||
// If drag'n'drop an image from the another web page, if won't add "Files" to the supported types, but only a "text/uri-list".
|
|||
// With "text/uri-list" browser can add actual file as well.
|
|||
var filesCount = _dataObject.GetPropertyAsJSObject("files")?.GetPropertyAsInt32("count"); |
|||
if (filesCount > 0) |
|||
{ |
|||
dataFormats.Add(DataFormats.Files); |
|||
} |
|||
|
|||
return dataFormats; |
|||
} |
|||
|
|||
public bool Contains(string dataFormat) |
|||
{ |
|||
return GetDataFormats().Contains(dataFormat); |
|||
} |
|||
|
|||
public object? Get(string dataFormat) |
|||
{ |
|||
if (dataFormat == DataFormats.Files) |
|||
{ |
|||
var files = _dataObject.GetPropertyAsJSObject("files"); |
|||
if (files is not null) |
|||
{ |
|||
return StorageHelper.FilesToItemsArray(files) |
|||
.Select(reference => reference.GetPropertyAsString("kind") switch |
|||
{ |
|||
"directory" => (IStorageItem)new JSStorageFolder(reference), |
|||
"file" => new JSStorageFile(reference), |
|||
_ => null |
|||
}) |
|||
.Where(i => i is not null) |
|||
.ToArray()!; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
if (dataFormat == DataFormats.Text) |
|||
{ |
|||
if (_dataObject.CallMethodString("getData", "text/plain") is { Length :> 0 } textData) |
|||
{ |
|||
return textData; |
|||
} |
|||
} |
|||
|
|||
if (_dataObject.CallMethodString("getData", dataFormat) is { Length: > 0 } data) |
|||
{ |
|||
return data; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System.Runtime.InteropServices.JavaScript; |
|||
|
|||
namespace Avalonia.Browser.Interop; |
|||
|
|||
internal static partial class GeneralHelpers |
|||
{ |
|||
[JSImport("GeneralHelpers.itemsArrayAt", AvaloniaModule.MainModuleName)] |
|||
public static partial JSObject[] ItemsArrayAt(JSObject jsObject, string key); |
|||
public static JSObject[] GetPropertyAsJSObjectArray(this JSObject jsObject, string key) => ItemsArrayAt(jsObject, key); |
|||
|
|||
[JSImport("GeneralHelpers.itemsArrayAt", AvaloniaModule.MainModuleName)] |
|||
public static partial string[] ItemsArrayAtAsStrings(JSObject jsObject, string key); |
|||
public static string[] GetPropertyAsStringArray(this JSObject jsObject, string key) => ItemsArrayAtAsStrings(jsObject, key); |
|||
|
|||
[JSImport("GeneralHelpers.callMethod", AvaloniaModule.MainModuleName)] |
|||
public static partial string IntCallMethodString(JSObject jsObject, string name); |
|||
[JSImport("GeneralHelpers.callMethod", AvaloniaModule.MainModuleName)] |
|||
public static partial string IntCallMethodStringString(JSObject jsObject, string name, string arg1); |
|||
|
|||
public static string CallMethodString(this JSObject jsObject, string name) => IntCallMethodString(jsObject, name); |
|||
public static string CallMethodString(this JSObject jsObject, string name, string arg1) => IntCallMethodStringString(jsObject, name, arg1); |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
export class GeneralHelpers { |
|||
public static itemsArrayAt(instance: any, key: string): any[] { |
|||
const items = instance[key]; |
|||
if (!items) { |
|||
return []; |
|||
} |
|||
|
|||
const retItems = []; |
|||
for (let i = 0; i < items.length; i++) { |
|||
retItems[i] = items[i]; |
|||
} |
|||
return retItems; |
|||
} |
|||
|
|||
public static callMethod(instance: any, name: string /*, args */): any { |
|||
const args = Array.prototype.slice.call(arguments, 2); |
|||
return instance[name].apply(instance, args); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue