Prechádzať zdrojové kódy

Use `avares://` scheme with proper relative uri handling

Nikita Tsukanov 7 rokov pred
rodič
commit
b092c51a55

+ 2 - 2
samples/ControlCatalog/App.xaml

@@ -2,8 +2,8 @@
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              x:Class="ControlCatalog.App">
   <Application.Styles>
-      <StyleInclude Source="res:asm:Avalonia.Themes.Default/DefaultTheme.xaml"/>
-      <StyleInclude Source="res:asm:Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
+      <StyleInclude Source="avares://Avalonia.Themes.Default/DefaultTheme.xaml"/>
+      <StyleInclude Source="avares://Avalonia.Themes.Default/Accents/BaseLight.xaml"/>
     <Style Selector="TextBlock.h1">
       <Setter Property="FontSize" Value="{DynamicResource FontSizeLarge}"/>
       <Setter Property="FontWeight" Value="Medium"/>

+ 1 - 1
samples/ControlCatalog/MainWindow.xaml

@@ -1,6 +1,6 @@
 <Window xmlns="https://github.com/avaloniaui" MinWidth="500" MinHeight="300"
         Title="Avalonia Control Gallery"
-        Icon="/Assets/test_icon.ico?assembly=ControlCatalog"
+        Icon="/Assets/test_icon.ico"
         xmlns:local="clr-namespace:ControlCatalog"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         x:Class="ControlCatalog.MainWindow">

+ 4 - 4
samples/ControlCatalog/Pages/TextBoxPage.xaml

@@ -44,10 +44,10 @@
         
         <StackPanel Orientation="Vertical" Spacing="8">
             <TextBlock Classes="h2">res fonts</TextBlock>
-            <TextBox Width="200" Text="Custom font regular" FontWeight="Normal" FontStyle="Normal" FontFamily="res:asm:ControlCatalog/Assets/Fonts#Source Sans Pro"/>
-            <TextBox Width="200" Text="Custom font bold" FontWeight="Bold" FontStyle="Normal" FontFamily="res:asm:ControlCatalog/Assets/Fonts#Source Sans Pro"/>
-            <TextBox Width="200" Text="Custom font italic" FontWeight="Normal" FontStyle="Italic" FontFamily="res:asm:ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf#Source Sans Pro"/>
-            <TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="res:asm:ControlCatalog/Assets/Fonts/SourceSansPro-*.ttf#Source Sans Pro"/>
+            <TextBox Width="200" Text="Custom font regular" FontWeight="Normal" FontStyle="Normal" FontFamily="avares://ControlCatalog/Assets/Fonts#Source Sans Pro"/>
+            <TextBox Width="200" Text="Custom font bold" FontWeight="Bold" FontStyle="Normal" FontFamily="avares://ControlCatalog/Assets/Fonts#Source Sans Pro"/>
+            <TextBox Width="200" Text="Custom font italic" FontWeight="Normal" FontStyle="Italic" FontFamily="avares://ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf#Source Sans Pro"/>
+            <TextBox Width="200" Text="Custom font italic bold" FontWeight="Bold" FontStyle="Italic" FontFamily="avares://ControlCatalog/Assets/Fonts/SourceSansPro-*.ttf#Source Sans Pro"/>
         </StackPanel>
       </StackPanel>
   </StackPanel>

+ 1 - 1
src/Avalonia.DesignerSupport/DesignWindowLoader.cs

@@ -30,7 +30,7 @@ namespace Avalonia.DesignerSupport
                         xamlFileProjectPath = "/Designer/Fake.xaml";
                     //Fabricate fake Uri
                     baseUri =
-                        new Uri($"res:asm:{Path.GetFileNameWithoutExtension(assemblyPath)}{xamlFileProjectPath}");
+                        new Uri($"avares://{Path.GetFileNameWithoutExtension(assemblyPath)}{xamlFileProjectPath}");
                 }
 
                 var localAsm = assemblyPath != null ? Assembly.LoadFile(Path.GetFullPath(assemblyPath)) : null;

+ 2 - 2
src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs

@@ -231,7 +231,7 @@ namespace Avalonia.Markup.Xaml
         private static IEnumerable<Uri> GetUrisFor(IAssetLoader assetLocator, Type type)
         {
             var asm = type.GetTypeInfo().Assembly.GetName().Name;
-            var xamlInfoUri = new Uri($"res:asm:{asm}/!AvaloniaResourceXamlInfo");
+            var xamlInfoUri = new Uri($"avares://{asm}/!AvaloniaResourceXamlInfo");
             var typeName = type.FullName;
             if (typeName == null)
                 throw new ArgumentException("Type doesn't have a FullName");
@@ -243,7 +243,7 @@ namespace Avalonia.Markup.Xaml
                     var xamlInfo = (AvaloniaResourceXamlInfo)s_xamlInfoSerializer.ReadObject(xamlInfoStream);
                     if (xamlInfo.ClassToResourcePathIndex.TryGetValue(typeName, out var rv) == true)
                     {
-                        yield return new Uri($"res:asm:{asm}{rv}");
+                        yield return new Uri($"avares://{asm}{rv}");
                         yield break;
                     }
                 }

+ 21 - 31
src/Shared/PlatformSupport/AssetLoader.cs

@@ -20,20 +20,20 @@ namespace Avalonia.Shared.PlatformSupport
         private static readonly Dictionary<string, AssemblyDescriptor> AssemblyNameCache
             = new Dictionary<string, AssemblyDescriptor>();
 
-        private AssemblyDescriptor _defaultAssembly;
+        private AssemblyDescriptor _defaultResmAssembly;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="AssetLoader"/> class.
         /// </summary>
         /// <param name="assembly">
-        /// The default assembly from which to load assets for which no assembly is specified.
+        /// The default assembly from which to load resm: assets for which no assembly is specified.
         /// </param>
         public AssetLoader(Assembly assembly = null)
         {
             if (assembly == null)
                 assembly = Assembly.GetEntryAssembly();
             if (assembly != null)
-                _defaultAssembly = new AssemblyDescriptor(assembly);
+                _defaultResmAssembly = new AssemblyDescriptor(assembly);
         }
 
         /// <summary>
@@ -42,7 +42,7 @@ namespace Avalonia.Shared.PlatformSupport
         /// <param name="assembly">The default assembly.</param>
         public void SetDefaultAssembly(Assembly assembly)
         {
-            _defaultAssembly = new AssemblyDescriptor(assembly);
+            _defaultResmAssembly = new AssemblyDescriptor(assembly);
         }
 
         /// <summary>
@@ -115,7 +115,7 @@ namespace Avalonia.Shared.PlatformSupport
             }
 
             uri = EnsureAbsolute(uri, baseUri);
-            if (uri.Scheme == "res")
+            if (uri.Scheme == "avares")
             {
                 var (asm, path) = GetResAsmAndPath(uri);
                 if (asm == null)
@@ -129,7 +129,7 @@ namespace Avalonia.Shared.PlatformSupport
                     return Enumerable.Empty<Uri>();
                 path = path.TrimEnd('/') + '/';
                 return asm.AvaloniaResources.Where(r => r.Key.StartsWith(path))
-                    .Select(x => new Uri($"res:asm:{asm.Name}{x.Key}"));
+                    .Select(x => new Uri($"avares://{asm.Name}{x.Key}"));
             }
 
             return Enumerable.Empty<Uri>();
@@ -153,7 +153,7 @@ namespace Avalonia.Shared.PlatformSupport
         {           
             if (uri.IsAbsoluteUri && uri.Scheme == "resm")
             {
-                var asm = GetAssembly(uri) ?? GetAssembly(baseUri) ?? _defaultAssembly;
+                var asm = GetAssembly(uri) ?? GetAssembly(baseUri) ?? _defaultResmAssembly;
 
                 if (asm == null)
                 {
@@ -171,13 +171,9 @@ namespace Avalonia.Shared.PlatformSupport
 
             uri = EnsureAbsolute(uri, baseUri);
 
-            if (uri.Scheme == "res")
+            if (uri.Scheme == "avares")
             {
                 var (asm, path) = GetResAsmAndPath(uri);
-                if(asm == null)
-                    throw new ArgumentException(
-                        "No default assembly, entry assembly or explicit assembly specified; " +
-                        "don't know where to look up for the resource, try specifying assembly explicitly.");
                 if (asm.AvaloniaResources == null)
                     return null;
                 asm.AvaloniaResources.TryGetValue(path, out var desc);
@@ -189,18 +185,8 @@ namespace Avalonia.Shared.PlatformSupport
 
         private (AssemblyDescriptor asm, string path) GetResAsmAndPath(Uri uri)
         {
-            string path = null, asmPart = null;
-            if (!uri.AbsolutePath.StartsWith("asm:"))
-                path = uri.AbsolutePath;
-            else
-            {
-                var sp = uri.AbsolutePath.Split(new[] {'/'}, 2);
-                asmPart = sp[0].Substring(4);
-                path = '/' + sp[1];
-            }
-
-            var asm = (asmPart == null ? null : GetAssembly(asmPart)) ?? _defaultAssembly;
-            return (asm, path);
+            var asm = GetAssembly(uri.Authority);
+            return (asm, uri.AbsolutePath);
         }
         
         private AssemblyDescriptor GetAssembly(Uri uri)
@@ -209,7 +195,7 @@ namespace Avalonia.Shared.PlatformSupport
             {
                 if (!uri.IsAbsoluteUri)
                     return null;
-                if (uri.Scheme == "res")
+                if (uri.Scheme == "avares")
                     return GetResAsmAndPath(uri).asm;
 
                 if (uri.Scheme == "resm")
@@ -230,9 +216,7 @@ namespace Avalonia.Shared.PlatformSupport
         private AssemblyDescriptor GetAssembly(string name)
         {
             if (name == null)
-            {
-                return _defaultAssembly;
-            }
+                throw new ArgumentNullException(nameof(name));
 
             AssemblyDescriptor rv;
             if (!AssemblyNameCache.TryGetValue(name, out rv))
@@ -247,9 +231,7 @@ namespace Avalonia.Shared.PlatformSupport
                 {
                     // iOS does not support loading assemblies dynamically!
                     //
-#if NETCOREAPP1_0
-                    AssemblyNameCache[name] = rv = new AssemblyDescriptor(Assembly.Load(new AssemblyName(name)));
-#elif __IOS__
+#if __IOS__
                     throw new InvalidOperationException(
                         $"Assembly {name} needs to be referenced and explicitly loaded before loading resources");
 #else
@@ -400,5 +382,13 @@ namespace Avalonia.Shared.PlatformSupport
             public Dictionary<string, IAssetDescriptor> AvaloniaResources { get; }
             public string Name { get; }
         }
+        
+        public static void RegisterResUriParsers()
+        {
+            UriParser.Register(new GenericUriParser(GenericUriParserOptions.GenericAuthority |
+                                                    GenericUriParserOptions.NoUserInfo |
+                                                    GenericUriParserOptions.NoPort | GenericUriParserOptions.NoQuery |
+                                                    GenericUriParserOptions.NoFragment), "avares", -1);
+        }
     }
 }

+ 1 - 0
src/Shared/PlatformSupport/StandardRuntimePlatformServices.cs

@@ -10,6 +10,7 @@ namespace Avalonia.Shared.PlatformSupport
         public static void Register(Assembly assembly = null)
         {
             var standardPlatform = new StandardRuntimePlatform();
+            AssetLoader.RegisterResUriParsers();
             AvaloniaLocator.CurrentMutable
                 .Bind<IRuntimePlatform>().ToConstant(standardPlatform)
                 .Bind<IAssetLoader>().ToConstant(new AssetLoader(assembly))