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