diff --git a/src/Directory.Build.props b/src/Directory.Build.props index c41d3b1..9ff16ca 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,7 +1,8 @@ - + unoplatform + 11 https://github.com/unoplatform/uno.xamlmerge.task https://nv-assets.azurewebsites.net/logos/uno.png https://github.com/unoplatform/uno.xamlmerge.task diff --git a/src/Uno.XamlMerge.Task/BatchMergeXaml.cs b/src/Uno.XamlMerge.Task/BatchMergeXaml.cs index 188ee1e..6aaedee 100644 --- a/src/Uno.XamlMerge.Task/BatchMergeXaml.cs +++ b/src/Uno.XamlMerge.Task/BatchMergeXaml.cs @@ -11,6 +11,7 @@ using System.Diagnostics; using System.IO; using System.Linq; +using System.Text; using System.Xml; namespace Uno.UI.Tasks.BatchMerge @@ -28,6 +29,8 @@ public class BatchMergeXaml_v0 : CustomTask [Required] public string ProjectFullPath { get; set; } + public bool IsHotReloadEnabled { get; set; } + [Output] public string[] FilesWritten => _filesWritten.ToArray(); @@ -44,6 +47,12 @@ public override bool Execute() var filteredPages = Pages.ToList(); filteredPages.RemoveAll(e => MergedXamlFiles.Any(m => FullPathComparer.Default.Equals(e, m))); + if (IsHotReloadEnabled) + { + GenerateForHotReload(filteredPages); + return !HasLoggedErrors; + } + if (MergedXamlFiles.Length > 1) { foreach (var mergedXamlFile in MergedXamlFiles) @@ -69,6 +78,71 @@ public override bool Execute() return !HasLoggedErrors; } + private string GenerateMergedDictionariesForHotReload(IEnumerable filteredPages) + { + var projectBasePath = Path.GetDirectoryName(Path.GetFullPath(ProjectFullPath)); + + var builder = new StringBuilder(); + builder.Append(""" + + + + + + """); + + foreach (var page in filteredPages) + { + var pagePath = Path.GetFullPath(page.ItemSpec).Replace(projectBasePath, "").TrimStart(Path.DirectorySeparatorChar).Replace('\\', '/'); + builder.Append($""" + + + """); + } + + builder.Append(""" + + + + """); + + return builder.ToString(); + } + + /// + /// When HotReload is enabled, we want modifications to the original XAML files to be reflected. + /// This cannot be achieved when an actual merge happens. + /// So, for HotReload, we'll generate a XAML file that only references the original XAML files and not do an actual merge. + /// This way, it can work with HotReload perfectly. + /// + private void GenerateForHotReload(List filteredPages) + { + if (MergedXamlFiles.Length > 1) + { + foreach (var mergedXamlFile in MergedXamlFiles) + { + var mergeFileName = Path.GetFileName(mergedXamlFile.ItemSpec); + string fileContents = GenerateMergedDictionariesForHotReload(filteredPages.Where(p => string.Equals(p.GetMetadata("MergeFile"), mergeFileName, StringComparison.OrdinalIgnoreCase))); + + Directory.CreateDirectory(Path.GetDirectoryName(mergedXamlFile.ItemSpec)); + Utils.RewriteFileIfNecessary(mergedXamlFile.ItemSpec, fileContents); + } + } + else if (MergedXamlFiles.Length == 1) + { + // Single target file, without "MergeFile" attribution + var mergedXamlFile = MergedXamlFiles[0]; + var mergeFileName = Path.GetFileName(mergedXamlFile.ItemSpec); + string fileContents = GenerateMergedDictionariesForHotReload(filteredPages); + + Directory.CreateDirectory(Path.GetDirectoryName(mergedXamlFile.ItemSpec)); + Utils.RewriteFileIfNecessary(mergedXamlFile.ItemSpec, fileContents); + } + } + private void ValidatePageMergeFileMetadata() { if (MergedXamlFiles.Length > 1) diff --git a/src/Uno.XamlMerge.Task/Uno.XamlMerge.Task.csproj b/src/Uno.XamlMerge.Task/Uno.XamlMerge.Task.csproj index 609dfc6..df75650 100644 --- a/src/Uno.XamlMerge.Task/Uno.XamlMerge.Task.csproj +++ b/src/Uno.XamlMerge.Task/Uno.XamlMerge.Task.csproj @@ -4,7 +4,6 @@ netstandard2.0 enable enable - 10.0 True true Uno.XamlMerge.Task.v0 diff --git a/src/Uno.XamlMerge.Task/build/Uno.XamlMerge.Task.targets b/src/Uno.XamlMerge.Task/build/Uno.XamlMerge.Task.targets index 70a394c..9cbe29d 100644 --- a/src/Uno.XamlMerge.Task/build/Uno.XamlMerge.Task.targets +++ b/src/Uno.XamlMerge.Task/build/Uno.XamlMerge.Task.targets @@ -12,9 +12,14 @@ DependsOnTargets="_XamlMergeFillProperties" Condition="'$(BuildingProject)' == 'true' or '$(DesignTimeBuild)' != 'true'"> + + true + + @@ -26,7 +31,7 @@ DependsOnTargets="_XamlMergeFillProperties"> - + new TaskItem(Path.Combine(basePath, "Output", f))) .ToArray(); + task.IsHotReloadEnabled = isHotReloadEnabled; return task; } diff --git a/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/Input_Dictionary_1.xml b/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/Input_Dictionary_1.xml new file mode 100644 index 0000000..2e86580 --- /dev/null +++ b/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/Input_Dictionary_1.xml @@ -0,0 +1,7 @@ + + + Value1 + diff --git a/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/Input_Dictionary_2.xml b/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/Input_Dictionary_2.xml new file mode 100644 index 0000000..6600e4b --- /dev/null +++ b/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/Input_Dictionary_2.xml @@ -0,0 +1,7 @@ + + + Value2 + diff --git a/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/expected.xml b/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/expected.xml new file mode 100644 index 0000000..8928c90 --- /dev/null +++ b/src/Uno.XamlMerge.Tests/Scenarios/When_HR_Enabled/expected.xml @@ -0,0 +1,11 @@ + + + + + + + + diff --git a/src/Uno.XamlMerge.Tests/Uno.XamlMerge.Tests.csproj b/src/Uno.XamlMerge.Tests/Uno.XamlMerge.Tests.csproj index 5dfaa88..db6caee 100644 --- a/src/Uno.XamlMerge.Tests/Uno.XamlMerge.Tests.csproj +++ b/src/Uno.XamlMerge.Tests/Uno.XamlMerge.Tests.csproj @@ -2,7 +2,6 @@ net7.0;net461 - 10 enable false