diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 55703d1509..fc417147d3 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -22,7 +22,7 @@ not want this to happen as the alpha of the next major is, really, the next major already. --> - + diff --git a/src/Umbraco.Core/IO/FileSystemExtensions.cs b/src/Umbraco.Core/IO/FileSystemExtensions.cs index 4b73e64e80..ade2c58b38 100644 --- a/src/Umbraco.Core/IO/FileSystemExtensions.cs +++ b/src/Umbraco.Core/IO/FileSystemExtensions.cs @@ -65,5 +65,33 @@ namespace Umbraco.Core.IO } fs.DeleteFile(tempFile); } + + /// + /// Unwraps a filesystem. + /// + /// + /// A filesystem can be wrapped in a (public) or a (internal), + /// and this method deals with the various wrappers and + /// + public static IFileSystem Unwrap(this IFileSystem filesystem) + { + var unwrapping = true; + while (unwrapping) + { + switch (filesystem) + { + case FileSystemWrapper wrapper: + filesystem = wrapper.InnerFileSystem; + break; + case ShadowWrapper shadow: + filesystem = shadow.InnerFileSystem; + break; + default: + unwrapping = false; + break; + } + } + return filesystem; + } } } diff --git a/src/Umbraco.Core/IO/FileSystemWrapper.cs b/src/Umbraco.Core/IO/FileSystemWrapper.cs index a493b7166b..14d028c16d 100644 --- a/src/Umbraco.Core/IO/FileSystemWrapper.cs +++ b/src/Umbraco.Core/IO/FileSystemWrapper.cs @@ -21,7 +21,7 @@ namespace Umbraco.Core.IO InnerFileSystem = innerFileSystem; } - public IFileSystem InnerFileSystem { get; internal set; } + internal IFileSystem InnerFileSystem { get; set; } public IEnumerable GetDirectories(string path) { diff --git a/src/Umbraco.Core/IO/ShadowWrapper.cs b/src/Umbraco.Core/IO/ShadowWrapper.cs index 94bd61b162..6493238391 100644 --- a/src/Umbraco.Core/IO/ShadowWrapper.cs +++ b/src/Umbraco.Core/IO/ShadowWrapper.cs @@ -75,6 +75,8 @@ namespace Umbraco.Core.IO } } + public IFileSystem InnerFileSystem => _innerFileSystem; + private IFileSystem FileSystem { get diff --git a/src/Umbraco.Tests/IO/FileSystemsTests.cs b/src/Umbraco.Tests/IO/FileSystemsTests.cs index d1aeb1a3fa..52de1bbcfa 100644 --- a/src/Umbraco.Tests/IO/FileSystemsTests.cs +++ b/src/Umbraco.Tests/IO/FileSystemsTests.cs @@ -86,6 +86,16 @@ namespace Umbraco.Tests.IO Assert.AreSame(fileSystem1, fileSystem2); } + [Test] + public void Can_Unwrap_MediaFileSystem() + { + var fileSystem = _factory.GetInstance(); + var unwrapped = fileSystem.Unwrap(); + Assert.IsNotNull(unwrapped); + var physical = unwrapped as PhysicalFileSystem; + Assert.IsNotNull(physical); + } + [Test] public void Can_Delete_MediaFiles() { diff --git a/src/Umbraco.Web.UI.Client/src/common/filters/safehtml.filter.js b/src/Umbraco.Web.UI.Client/src/common/filters/safehtml.filter.js new file mode 100644 index 0000000000..50d8574306 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/common/filters/safehtml.filter.js @@ -0,0 +1,6 @@ +angular.module('umbraco.filters') + .filter('safe_html', ['$sce', function($sce){ + return function(text) { + return $sce.trustAsHtml(text); + }; + }]); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html b/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html index 72cc3ddb06..0478e6ba3c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html +++ b/src/Umbraco.Web.UI.Client/src/views/dashboard/default/StartupDashboardIntro.html @@ -19,7 +19,7 @@
-
+
@@ -65,7 +65,7 @@ - + \ No newline at end of file diff --git a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs index a73734fab8..528c87b2bb 100644 --- a/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs +++ b/src/Umbraco.Web/Scheduling/BackgroundTaskRunner.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; using System.Web.Hosting; using Umbraco.Core; -using Umbraco.Core.Composing; using Umbraco.Core.Events; using Umbraco.Core.Logging; @@ -15,7 +14,43 @@ namespace Umbraco.Web.Scheduling /// /// This class exists for logging purposes - the one you want to use is BackgroundTaskRunner{T}. public abstract class BackgroundTaskRunner - { } + { + /// + /// Creates a hook, to hook the task runner into the main domain. + /// + /// The object. + /// A method to execute when hooking into the main domain. + /// A method to execute when the main domain releases. + /// + public MainDomHook CreateMainDomHook(IMainDom mainDom, Action install, Action release) + { + return new MainDomHook(mainDom, install, release); + } + + public class MainDomHook + { + public MainDomHook(IMainDom mainDom, Action install, Action release) + { + MainDom = mainDom; + Install = install; + Release = release; + } + + public IMainDom MainDom { get; } + public Action Install { get; } + public Action Release { get; } + + internal bool Register() + { + if (MainDom != null) + return MainDom.Register(Install, Release); + + // tests + Install?.Invoke(); + return true; + } + } + } /// /// Manages a queue of tasks of type and runs them in the background. @@ -55,42 +90,6 @@ namespace Umbraco.Web.Scheduling private bool _terminated; // remember we've terminated private readonly TaskCompletionSource _terminatedSource = new TaskCompletionSource(); // enable awaiting termination - // fixme - this is temp - // at the moment MainDom is internal so we have to find a way to hook into it - temp - public class MainDomHook - { - private MainDomHook(MainDom mainDom, Action install, Action release) - { - MainDom = mainDom; - Install = install; - Release = release; - } - - internal MainDom MainDom { get; } - public Action Install { get; } - public Action Release { get; } - - public static MainDomHook Create(Action install, Action release) - { - return new MainDomHook(Core.Composing.Current.Factory.GetInstance(), install, release); - } - - public static MainDomHook CreateForTest(Action install, Action release) - { - return new MainDomHook(null, install, release); - } - - public bool Register() - { - if (MainDom != null) - return MainDom.Register(Install, Release); - - // tests - Install?.Invoke(); - return true; - } - } - /// /// Initializes a new instance of the class. /// @@ -129,11 +128,9 @@ namespace Umbraco.Web.Scheduling /// An optional main domain hook. public BackgroundTaskRunner(string name, BackgroundTaskRunnerOptions options, ILogger logger, MainDomHook hook = null) { - if (options == null) throw new ArgumentNullException(nameof(options)); - if (logger == null) throw new ArgumentNullException(nameof(logger)); - _options = options; + _options = options ?? throw new ArgumentNullException(nameof(options)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _logPrefix = "[" + name + "] "; - _logger = logger; if (options.Hosted) HostingEnvironment.RegisterObject(this); @@ -319,7 +316,7 @@ namespace Umbraco.Web.Scheduling } /// - /// Shuts the taks runner down. + /// Shuts the tasks runner down. /// /// True for force the runner to stop. /// True to wait until the runner has stopped. @@ -355,7 +352,7 @@ namespace Umbraco.Web.Scheduling // tasks in the queue will be executed... if (wait == false) return; - _runningTask?.Wait(); // wait for whatever is running to end... + _runningTask?.Wait(CancellationToken.None); // wait for whatever is running to end... } private async Task Pump() @@ -648,13 +645,13 @@ namespace Umbraco.Web.Scheduling #endregion /// - /// Requests a registered object to unregister. + /// Requests a registered object to un-register. /// - /// true to indicate the registered object should unregister from the hosting + /// true to indicate the registered object should un-register from the hosting /// environment before returning; otherwise, false. /// /// "When the application manager needs to stop a registered object, it will call the Stop method." - /// The application manager will call the Stop method to ask a registered object to unregister. During + /// The application manager will call the Stop method to ask a registered object to un-register. During /// processing of the Stop method, the registered object must call the HostingEnvironment.UnregisterObject method. /// public void Stop(bool immediate)