diff --git a/.editorconfig b/.editorconfig index c63ef39430..5a35b71ce6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -34,4 +34,7 @@ dotnet_naming_style.prefix_underscore.required_prefix = _ csharp_style_var_for_built_in_types = true:suggestion csharp_style_var_when_type_is_apparent = true:suggestion csharp_style_var_elsewhere = true:suggestion -csharp_prefer_braces = false : none +csharp_prefer_braces = false : none + +[*.{js,less}] +trim_trailing_whitespace = false diff --git a/.github/README.md b/.github/README.md index 5a1340006e..ba5293e8c2 100644 --- a/.github/README.md +++ b/.github/README.md @@ -6,7 +6,7 @@ _Ready to try out Version 8? [See the quick start guide](V8_GETTING_STARTED.md). When is Umbraco 8 coming? ========================= -When it's ready. We're done with the major parts of the architecture work and are focusing on three seperate tracks to prepare Umbraco 8 for release: +When it's ready. We're done with the major parts of the architecture work and are focusing on three separate tracks to prepare Umbraco 8 for release: 1) Editor Track (_currently in progress_). Without editors, there's no market for Umbraco. So we want to make sure that Umbraco 8 is full of love for editors. 2) Partner Track. Without anyone implementing Umbraco, there's nothing for editors to update. So we want to make sure that Umbraco 8 is a joy to implement 3) Contributor Track. Without our fabulous ecosystem of both individual Umbracians and 3rd party ISVs, Umbraco wouldn't be as rich a platform as it is today. We want to make sure that it's easy, straight forward and as backwards-compatible as possible to create packages for Umbraco diff --git a/.gitignore b/.gitignore index 279bdb39dd..57b4e18aaa 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ *.suo *.vs10x *.ndproj +*.ignorer.* # common directories .DS_Store @@ -156,4 +157,4 @@ build/temp/ -# eof \ No newline at end of file +# eof diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index 3cb3d0d875..a188377c19 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -52,10 +52,8 @@ - - diff --git a/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs b/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs index ca86f623cc..7fba47a2cd 100644 --- a/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs +++ b/src/Umbraco.Core/Composing/Composers/ConfigurationComposer.cs @@ -15,7 +15,6 @@ namespace Umbraco.Core.Composing.Composers // register others composition.RegisterUnique(factory => factory.GetInstance().Content); - composition.RegisterUnique(factory => factory.GetInstance().Templates); composition.RegisterUnique(factory => factory.GetInstance().RequestHandler); composition.RegisterUnique(factory => factory.GetInstance().Security); diff --git a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs index 8c9ccd1088..3f1bc1df5e 100644 --- a/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs +++ b/src/Umbraco.Core/Composing/Composers/ServicesComposer.cs @@ -73,11 +73,6 @@ namespace Umbraco.Core.Composing.Composers factory.GetInstance(), factory.GetInstance(), new DirectoryInfo(IOHelper.GetRootDirectorySafe()))); - //TODO: These are replaced in the web project - we need to declare them so that - // something is wired up, just not sure this is very nice but will work for now. - composition.RegisterUnique(); - composition.RegisterUnique(); - return composition; } @@ -88,7 +83,7 @@ namespace Umbraco.Core.Composing.Composers /// /// private static PackagesRepository CreatePackageRepository(IFactory factory, string packageRepoFileName) - => new PackagesRepository( + => new PackagesRepository( factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), factory.GetInstance(), packageRepoFileName); diff --git a/src/Umbraco.Core/Composing/TypeLoader.cs b/src/Umbraco.Core/Composing/TypeLoader.cs index acb12ab575..4c4139848d 100644 --- a/src/Umbraco.Core/Composing/TypeLoader.cs +++ b/src/Umbraco.Core/Composing/TypeLoader.cs @@ -185,9 +185,7 @@ namespace Umbraco.Core.Composing // the app code folder and everything in it new Tuple(new DirectoryInfo(IOHelper.MapPath("~/App_Code")), false), // global.asax (the app domain also monitors this, if it changes will do a full restart) - new Tuple(new FileInfo(IOHelper.MapPath("~/global.asax")), false), - // trees.config - use the contents to create the hash since this gets resaved on every app startup! - new Tuple(new FileInfo(IOHelper.MapPath(SystemDirectories.Config + "/trees.config")), true) + new Tuple(new FileInfo(IOHelper.MapPath("~/global.asax")), false) }, _logger); return _currentAssembliesHash; diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/ITemplatesSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/ITemplatesSection.cs deleted file mode 100644 index 67fd58030b..0000000000 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/ITemplatesSection.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -namespace Umbraco.Core.Configuration.UmbracoSettings -{ - public interface ITemplatesSection : IUmbracoConfigurationSection - { - RenderingEngine DefaultRenderingEngine { get; } - } -} diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/IUmbracoSettingsSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/IUmbracoSettingsSection.cs index 28da03ff2d..33416d38cc 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/IUmbracoSettingsSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/IUmbracoSettingsSection.cs @@ -1,5 +1,4 @@ using System; -using System.ComponentModel; namespace Umbraco.Core.Configuration.UmbracoSettings { @@ -12,8 +11,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings ISecuritySection Security { get; } IRequestHandlerSection RequestHandler { get; } - - ITemplatesSection Templates { get; } ILoggingSection Logging { get; } @@ -22,6 +19,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings IProvidersSection Providers { get; } IWebRoutingSection WebRouting { get; } - } } diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/TemplatesElement.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/TemplatesElement.cs deleted file mode 100644 index 8c929b02d8..0000000000 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/TemplatesElement.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Configuration; - -namespace Umbraco.Core.Configuration.UmbracoSettings -{ - internal class TemplatesElement : UmbracoConfigurationElement, ITemplatesSection - { - [ConfigurationProperty("defaultRenderingEngine", IsRequired = true)] - internal InnerTextConfigurationElement DefaultRenderingEngine - { - get { return GetOptionalTextElement("defaultRenderingEngine", RenderingEngine.Mvc); } - } - - RenderingEngine ITemplatesSection.DefaultRenderingEngine - { - get { return DefaultRenderingEngine; } - } - - } -} diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings/UmbracoSettingsSection.cs b/src/Umbraco.Core/Configuration/UmbracoSettings/UmbracoSettingsSection.cs index d36410f317..9ed635f6a9 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings/UmbracoSettingsSection.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings/UmbracoSettingsSection.cs @@ -1,11 +1,7 @@ -using System; -using System.ComponentModel; -using System.Configuration; -using System.Linq; +using System.Configuration; namespace Umbraco.Core.Configuration.UmbracoSettings { - public class UmbracoSettingsSection : ConfigurationSection, IUmbracoSettingsSection { [ConfigurationProperty("backOffice")] @@ -32,12 +28,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings get { return (RequestHandlerElement)this["requestHandler"]; } } - [ConfigurationProperty("templates")] - internal TemplatesElement Templates - { - get { return (TemplatesElement)this["templates"]; } - } - [ConfigurationProperty("logging")] internal LoggingElement Logging { @@ -77,11 +67,6 @@ namespace Umbraco.Core.Configuration.UmbracoSettings get { return RequestHandler; } } - ITemplatesSection IUmbracoSettingsSection.Templates - { - get { return Templates; } - } - IBackOfficeSection IUmbracoSettingsSection.BackOffice { get { return BackOffice; } @@ -106,6 +91,5 @@ namespace Umbraco.Core.Configuration.UmbracoSettings { get { return WebRouting; } } - } } diff --git a/src/Umbraco.Core/Deploy/IGridCellValueConnector.cs b/src/Umbraco.Core/Deploy/IGridCellValueConnector.cs index 827a902b89..15ed404d31 100644 --- a/src/Umbraco.Core/Deploy/IGridCellValueConnector.cs +++ b/src/Umbraco.Core/Deploy/IGridCellValueConnector.cs @@ -22,20 +22,17 @@ namespace Umbraco.Core.Deploy /// Gets the value to be deployed from the control value as a string. /// /// The control containing the value. - /// The property where the control is located. Do not modify - only used for context /// The dependencies of the property. /// The grid cell value to be deployed. /// Note that - string GetValue(GridValue.GridControl gridControl, Property property, ICollection dependencies); + string GetValue(GridValue.GridControl gridControl, ICollection dependencies); /// /// Allows you to modify the value of a control being deployed. /// /// The control being deployed. - /// The property where the is located. Do not modify - only used for context. /// Follows the pattern of the property value connectors (). The SetValue method is used to modify the value of the . - /// Note that only the value should be modified - not the . - /// The should only be used to assist with context data relevant when setting the value. - void SetValue(GridValue.GridControl gridControl, Property property); + + void SetValue(GridValue.GridControl gridControl); } } diff --git a/src/Umbraco.Core/Deploy/IValueConnector.cs b/src/Umbraco.Core/Deploy/IValueConnector.cs index 92589ab6cf..7d9f43b5fe 100644 --- a/src/Umbraco.Core/Deploy/IValueConnector.cs +++ b/src/Umbraco.Core/Deploy/IValueConnector.cs @@ -20,16 +20,18 @@ namespace Umbraco.Core.Deploy /// Gets the deploy property value corresponding to a content property value, and gather dependencies. /// /// The content property value. + /// The value property type /// The content dependencies. /// The deploy property value. - string ToArtifact(object value, ICollection dependencies); + string ToArtifact(object value, PropertyType propertyType, ICollection dependencies); /// /// Gets the content property value corresponding to a deploy property value. /// /// The deploy property value. + /// The value property type< /// The current content property value. /// The content property value. - object FromArtifact(string value, object currentValue); + object FromArtifact(string value, PropertyType propertyType, object currentValue); } } diff --git a/src/Umbraco.Core/IO/FileSystems.cs b/src/Umbraco.Core/IO/FileSystems.cs index 7fc846319b..63a1259acb 100644 --- a/src/Umbraco.Core/IO/FileSystems.cs +++ b/src/Umbraco.Core/IO/FileSystems.cs @@ -19,7 +19,6 @@ namespace Umbraco.Core.IO private ShadowWrapper _partialViewsFileSystem; private ShadowWrapper _stylesheetsFileSystem; private ShadowWrapper _scriptsFileSystem; - private ShadowWrapper _masterPagesFileSystem; private ShadowWrapper _mvcViewsFileSystem; // well-known file systems lazy initialization @@ -102,16 +101,6 @@ namespace Umbraco.Core.IO } } - /// - public IFileSystem MasterPagesFileSystem - { - get - { - if (Volatile.Read(ref _wkfsInitialized) == false) EnsureWellKnownFileSystems(); - return _masterPagesFileSystem; - } - } - /// public IFileSystem MvcViewsFileSystem { @@ -135,14 +124,12 @@ namespace Umbraco.Core.IO var partialViewsFileSystem = new PhysicalFileSystem(SystemDirectories.PartialViews); var stylesheetsFileSystem = new PhysicalFileSystem(SystemDirectories.Css); var scriptsFileSystem = new PhysicalFileSystem(SystemDirectories.Scripts); - var masterPagesFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages); var mvcViewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews); _macroPartialFileSystem = new ShadowWrapper(macroPartialFileSystem, "Views/MacroPartials", IsScoped); _partialViewsFileSystem = new ShadowWrapper(partialViewsFileSystem, "Views/Partials", IsScoped); _stylesheetsFileSystem = new ShadowWrapper(stylesheetsFileSystem, "css", IsScoped); _scriptsFileSystem = new ShadowWrapper(scriptsFileSystem, "scripts", IsScoped); - _masterPagesFileSystem = new ShadowWrapper(masterPagesFileSystem, "masterpages", IsScoped); _mvcViewsFileSystem = new ShadowWrapper(mvcViewsFileSystem, "Views", IsScoped); // fixme locking? @@ -150,7 +137,6 @@ namespace Umbraco.Core.IO _shadowWrappers.Add(_partialViewsFileSystem); _shadowWrappers.Add(_stylesheetsFileSystem); _shadowWrappers.Add(_scriptsFileSystem); - _shadowWrappers.Add(_masterPagesFileSystem); _shadowWrappers.Add(_mvcViewsFileSystem); return null; diff --git a/src/Umbraco.Core/IO/IFileSystems.cs b/src/Umbraco.Core/IO/IFileSystems.cs index d74ad48145..f7d35058e3 100644 --- a/src/Umbraco.Core/IO/IFileSystems.cs +++ b/src/Umbraco.Core/IO/IFileSystems.cs @@ -25,11 +25,6 @@ /// IFileSystem ScriptsFileSystem { get; } - /// - /// Gets the masterpages filesystem. - /// - IFileSystem MasterPagesFileSystem { get; } - /// /// Gets the MVC views filesystem. /// diff --git a/src/Umbraco.Core/IO/MasterPageHelper.cs b/src/Umbraco.Core/IO/MasterPageHelper.cs deleted file mode 100644 index 049db04b9a..0000000000 --- a/src/Umbraco.Core/IO/MasterPageHelper.cs +++ /dev/null @@ -1,445 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Repositories; -using Umbraco.Core.Services; -using Umbraco.Core.Xml; - -namespace Umbraco.Core.IO -{ - internal class MasterPageHelper - { - private readonly IFileSystem _masterPageFileSystem; - internal static readonly string DefaultMasterTemplate = SystemDirectories.Umbraco + "/masterpages/default.master"; - //private static readonly char[] NewLineChars = Environment.NewLine.ToCharArray(); - - public MasterPageHelper(IFileSystem masterPageFileSystem) - { - if (masterPageFileSystem == null) throw new ArgumentNullException("masterPageFileSystem"); - _masterPageFileSystem = masterPageFileSystem; - } - - public bool MasterPageExists(ITemplate t) - { - return _masterPageFileSystem.FileExists(GetFilePath(t)); - } - - private string GetFilePath(ITemplate t) - { - return GetFilePath(t.Alias); - } - - private string GetFilePath(string alias) - { - return alias + ".master"; - } - - public string CreateMasterPage(ITemplate t, ITemplateRepository templateRepo, bool overWrite = false) - { - string masterpageContent = ""; - - var filePath = GetFilePath(t); - if (_masterPageFileSystem.FileExists(filePath) == false || overWrite) - { - masterpageContent = t.Content.IsNullOrWhiteSpace() ? CreateDefaultMasterPageContent(t, templateRepo) : t.Content; - - var data = Encoding.UTF8.GetBytes(masterpageContent); - var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray(); - - using (var ms = new MemoryStream(withBom)) - { - _masterPageFileSystem.AddFile(filePath, ms, true); - } - } - else - { - using (var s = _masterPageFileSystem.OpenFile(filePath)) - using (var tr = new StreamReader(s, Encoding.UTF8)) - { - masterpageContent = tr.ReadToEnd(); - tr.Close(); - } - } - - return masterpageContent; - } - - //internal string GetFileContents(ITemplate t) - //{ - // var masterpageContent = ""; - // if (_masterPageFileSystem.FileExists(GetFilePath(t))) - // { - // using (var s = _masterPageFileSystem.OpenFile(GetFilePath(t))) - // using (var tr = new StreamReader(s)) - // { - // masterpageContent = tr.ReadToEnd(); - // tr.Close(); - // } - // } - - // return masterpageContent; - //} - - public string UpdateMasterPageFile(ITemplate t, string currentAlias, ITemplateRepository templateRepo) - { - var template = UpdateMasterPageContent(t, currentAlias); - UpdateChildTemplates(t, currentAlias, templateRepo); - var filePath = GetFilePath(t); - - var data = Encoding.UTF8.GetBytes(template); - var withBom = Encoding.UTF8.GetPreamble().Concat(data).ToArray(); - - using (var ms = new MemoryStream(withBom)) - { - _masterPageFileSystem.AddFile(filePath, ms, true); - } - return template; - } - - private string CreateDefaultMasterPageContent(ITemplate template, ITemplateRepository templateRepo) - { - var design = new StringBuilder(); - design.Append(GetMasterPageHeader(template) + Environment.NewLine); - - if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) - { - var master = templateRepo.Get(template.MasterTemplateAlias); - if (master != null) - { - foreach (var cpId in GetContentPlaceholderIds(master)) - { - design.Append("" + - Environment.NewLine + - Environment.NewLine + - "" + - Environment.NewLine + - Environment.NewLine); - } - - return design.ToString(); - } - } - - design.Append(GetMasterContentElement(template) + Environment.NewLine); - design.Append(template.Content + Environment.NewLine); - design.Append("" + Environment.NewLine); - - return design.ToString(); - } - - public static IEnumerable GetContentPlaceholderIds(ITemplate template) - { - var retVal = new List(); - - var mp = template.Content; - var path = ""; - var r = new Regex(path, RegexOptions.IgnoreCase); - var m = r.Match(mp); - - while (m.Success) - { - var cc = m.Groups[3].Captures; - retVal.AddRange(cc.Cast().Where(c => c.Value != "server").Select(c => c.Value)); - - m = m.NextMatch(); - } - - return retVal; - } - - private static string UpdateMasterPageContent(ITemplate template, string currentAlias) - { - var masterPageContent = template.Content; - - if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias) - { - var masterHeader = - masterPageContent.Substring(0, masterPageContent.IndexOf("%>", StringComparison.Ordinal) + 2).Trim( - Environment.NewLine.ToCharArray()); - - // find the masterpagefile attribute - var m = Regex.Matches(masterHeader, "(?\\S*)=\"(?[^\"]*)\"", - RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - foreach (Match attributeSet in m) - { - if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile") - { - // validate the masterpagefile - var currentMasterPageFile = attributeSet.Groups["attributeValue"].Value; - var currentMasterTemplateFile = ParentTemplatePath(template); - - if (currentMasterPageFile != currentMasterTemplateFile) - { - masterPageContent = - masterPageContent.Replace( - attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"", - attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile + - "\""); - } - } - } - } - - return masterPageContent; - } - - private void UpdateChildTemplates(ITemplate template, string currentAlias, ITemplateRepository templateRepo) - { - //if we have a Old Alias if the alias and therefor the masterpage file name has changed... - //so before we save the new masterfile, we'll clear the old one, so we don't up with - //Unused masterpage files - if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias) - { - //Ensure that child templates have the right master masterpage file name - if (template.IsMasterTemplate) - { - var children = templateRepo.GetChildren(template.Id); - foreach (var t in children) - UpdateMasterPageFile(t, null, templateRepo); - } - } - } - - - //private void SaveDesignToFile(ITemplate t, string currentAlias, string design) - //{ - // //kill the old file.. - // if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != t.Alias) - // { - // var oldFile = - // IOHelper.MapPath(SystemDirectories.Masterpages + "/" + currentAlias.Replace(" ", "") + ".master"); - // if (System.IO.File.Exists(oldFile)) - // System.IO.File.Delete(oldFile); - // } - - // // save the file in UTF-8 - // System.IO.File.WriteAllText(GetFilePath(t), design, Encoding.UTF8); - //} - - //internal static void RemoveMasterPageFile(string alias) - //{ - // if (string.IsNullOrWhiteSpace(alias) == false) - // { - // string file = IOHelper.MapPath(SystemDirectories.Masterpages + "/" + alias.Replace(" ", "") + ".master"); - // if (System.IO.File.Exists(file)) - // System.IO.File.Delete(file); - // } - //} - - //internal string SaveTemplateToFile(ITemplate template, string currentAlias, ITemplateRepository templateRepo) - //{ - // var masterPageContent = template.Content; - // if (IsMasterPageSyntax(masterPageContent) == false) - // masterPageContent = ConvertToMasterPageSyntax(template); - - // // Add header to master page if it doesn't exist - // if (masterPageContent.TrimStart().StartsWith("<%@") == false) - // { - // masterPageContent = GetMasterPageHeader(template) + Environment.NewLine + masterPageContent; - // } - // else - // { - // // verify that the masterpage attribute is the same as the masterpage - // var masterHeader = - // masterPageContent.Substring(0, masterPageContent.IndexOf("%>", StringComparison.Ordinal) + 2).Trim(NewLineChars); - - // // find the masterpagefile attribute - // var m = Regex.Matches(masterHeader, "(?\\S*)=\"(?[^\"]*)\"", - // RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - // foreach (Match attributeSet in m) - // { - // if (attributeSet.Groups["attributeName"].Value.ToLower() == "masterpagefile") - // { - // // validate the masterpagefile - // var currentMasterPageFile = attributeSet.Groups["attributeValue"].Value; - // var currentMasterTemplateFile = ParentTemplatePath(template); - - // if (currentMasterPageFile != currentMasterTemplateFile) - // { - // masterPageContent = - // masterPageContent.Replace( - // attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterPageFile + "\"", - // attributeSet.Groups["attributeName"].Value + "=\"" + currentMasterTemplateFile + - // "\""); - - // } - // } - // } - - // } - - // //we have a Old Alias if the alias and therefor the masterpage file name has changed... - // //so before we save the new masterfile, we'll clear the old one, so we don't up with - // //Unused masterpage files - // if (string.IsNullOrEmpty(currentAlias) == false && currentAlias != template.Alias) - // { - - // //Ensure that child templates have the right master masterpage file name - // if (template.IsMasterTemplate) - // { - // var children = templateRepo.GetChildren(template.Id); - - // foreach (var t in children) - // UpdateMasterPageFile(t, null, templateRepo); - // } - - // //then kill the old file.. - // var oldFile = GetFilePath(currentAlias); - // if (_masterPageFileSystem.FileExists(oldFile)) - // _masterPageFileSystem.DeleteFile(oldFile); - // } - - // // save the file in UTF-8 - // System.IO.File.WriteAllText(GetFilePath(template), masterPageContent, Encoding.UTF8); - - // return masterPageContent; - //} - - //internal static string ConvertToMasterPageSyntax(ITemplate template) - //{ - // string masterPageContent = GetMasterContentElement(template) + Environment.NewLine; - - // masterPageContent += template.Content; - - // // Parse the design for getitems - // masterPageContent = EnsureMasterPageSyntax(template.Alias, masterPageContent); - - // // append ending asp:content element - // masterPageContent += Environment.NewLine + "" + Environment.NewLine; - - // return masterPageContent; - //} - - public static bool IsMasterPageSyntax(string code) - { - return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) || - code.InvariantContains("", ParentTemplatePath(template)) + Environment.NewLine; - } - - private static string ParentTemplatePath(ITemplate template) - { - var masterTemplate = DefaultMasterTemplate; - if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) - masterTemplate = SystemDirectories.Masterpages + "/" + template.MasterTemplateAlias + ".master"; - - return masterTemplate; - } - - internal static string GetMasterContentElement(ITemplate template) - { - if (template.MasterTemplateAlias.IsNullOrWhiteSpace() == false) - { - string masterAlias = template.MasterTemplateAlias; - return - String.Format("", masterAlias); - } - else - return - String.Format(""); - - } - - internal static string EnsureMasterPageSyntax(string templateAlias, string masterPageContent) - { - ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", true); - ReplaceElement(ref masterPageContent, "?UMBRACO_GETITEM", "umbraco:Item", false); - - // Parse the design for macros - ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", true); - ReplaceElement(ref masterPageContent, "?UMBRACO_MACRO", "umbraco:Macro", false); - - // Parse the design for load childs - masterPageContent = masterPageContent.Replace("", CreateDefaultPlaceHolder(templateAlias)) - .Replace("", CreateDefaultPlaceHolder(templateAlias)); - // Parse the design for aspnet forms - GetAspNetMasterPageForm(ref masterPageContent, templateAlias); - masterPageContent = masterPageContent.Replace("", ""); - // Parse the design for aspnet heads - masterPageContent = masterPageContent.Replace("", String.Format("", templateAlias.Replace(" ", ""))); - masterPageContent = masterPageContent.Replace("", ""); - return masterPageContent; - } - - - private static void GetAspNetMasterPageForm(ref string design, string templateAlias) - { - var formElement = Regex.Match(design, GetElementRegExp("?ASPNET_FORM", false), RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - if (string.IsNullOrEmpty(formElement.Value) == false) - { - string formReplace = String.Format("
", templateAlias.Replace(" ", "")); - if (formElement.Groups.Count == 0) - { - formReplace += ""; - } - design = design.Replace(formElement.Value, formReplace); - } - } - - private static string CreateDefaultPlaceHolder(string templateAlias) - { - return String.Format("", templateAlias.Replace(" ", "")); - } - - private static void ReplaceElement(ref string design, string elementName, string newElementName, bool checkForQuotes) - { - var m = - Regex.Matches(design, GetElementRegExp(elementName, checkForQuotes), - RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); - - foreach (Match match in m) - { - GroupCollection groups = match.Groups; - - // generate new element (compensate for a closing trail on single elements ("/")) - string elementAttributes = groups[1].Value; - // test for macro alias - if (elementName == "?UMBRACO_MACRO") - { - var tags = XmlHelper.GetAttributesFromElement(match.Value); - if (tags["macroAlias"] != null) - elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroAlias"]) + elementAttributes; - else if (tags["macroalias"] != null) - elementAttributes = String.Format(" Alias=\"{0}\"", tags["macroalias"]) + elementAttributes; - } - string newElement = "<" + newElementName + " runat=\"server\" " + elementAttributes.Trim() + ">"; - if (elementAttributes.EndsWith("/")) - { - elementAttributes = elementAttributes.Substring(0, elementAttributes.Length - 1); - } - else if (groups[0].Value.StartsWith(""; - - if (checkForQuotes) - { - // if it's inside quotes, we'll change element attribute quotes to single quotes - newElement = newElement.Replace("\"", "'"); - newElement = String.Format("\"{0}\"", newElement); - } - design = design.Replace(match.Value, newElement); - } - } - - private static string GetElementRegExp(string elementName, bool checkForQuotes) - { - if (checkForQuotes) - return String.Format("\"<[^>\\s]*\\b{0}(\\b[^>]*)>\"", elementName); - else - return String.Format("<[^>\\s]*\\b{0}(\\b[^>]*)>", elementName); - - } - - } -} diff --git a/src/Umbraco.Core/IO/SystemDirectories.cs b/src/Umbraco.Core/IO/SystemDirectories.cs index 4ea3ed64d5..8bea82ea4a 100644 --- a/src/Umbraco.Core/IO/SystemDirectories.cs +++ b/src/Umbraco.Core/IO/SystemDirectories.cs @@ -18,10 +18,6 @@ namespace Umbraco.Core.IO public static string Install => "~/install"; - //fixme: remove this - [Obsolete("Master pages are obsolete and code should be removed")] - public static string Masterpages => "~/masterpages"; - public static string AppCode => "~/App_Code"; public static string AppPlugins => "~/App_Plugins"; diff --git a/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs b/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs index 2d333ed916..1c6f9853a2 100644 --- a/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs +++ b/src/Umbraco.Core/Logging/Serilog/LoggerConfigExtensions.cs @@ -92,7 +92,7 @@ namespace Umbraco.Core.Logging.Serilog /// /// Reads settings from /config/serilog.user.config - /// That allows a seperate logging pipeline to be configured that wil not affect the main Umbraco log + /// That allows a separate logging pipeline to be configured that wil not affect the main Umbraco log /// /// A Serilog LoggerConfiguration public static LoggerConfiguration ReadFromUserConfigFile(this LoggerConfiguration logConfig) diff --git a/src/Umbraco.Core/Manifest/ManifestBackOfficeSection.cs b/src/Umbraco.Core/Manifest/ManifestBackOfficeSection.cs new file mode 100644 index 0000000000..a1b89d9a01 --- /dev/null +++ b/src/Umbraco.Core/Manifest/ManifestBackOfficeSection.cs @@ -0,0 +1,15 @@ +using System.Runtime.Serialization; +using Umbraco.Core.Models.Trees; + +namespace Umbraco.Core.Manifest +{ + [DataContract(Name = "section", Namespace = "")] + public class ManifestBackOfficeSection : IBackOfficeSection + { + [DataMember(Name = "alias")] + public string Alias { get; set; } + + [DataMember(Name = "name")] + public string Name { get; set; } + } +} diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs index 59753df66a..c471bbcf2e 100644 --- a/src/Umbraco.Core/Manifest/ManifestParser.cs +++ b/src/Umbraco.Core/Manifest/ManifestParser.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Exceptions; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models.ContentEditing; +using Umbraco.Core.Models.Trees; using Umbraco.Core.PropertyEditors; namespace Umbraco.Core.Manifest @@ -101,6 +102,7 @@ namespace Umbraco.Core.Manifest var gridEditors = new List(); var contentApps = new List(); var dashboards = new List(); + var sections = new List(); foreach (var manifest in manifests) { @@ -111,6 +113,7 @@ namespace Umbraco.Core.Manifest if (manifest.GridEditors != null) gridEditors.AddRange(manifest.GridEditors); if (manifest.ContentApps != null) contentApps.AddRange(manifest.ContentApps); if (manifest.Dashboards != null) dashboards.AddRange(manifest.Dashboards); + if (manifest.Sections != null) sections.AddRange(manifest.Sections.DistinctBy(x => x.Alias.ToLowerInvariant())); } return new PackageManifest @@ -121,7 +124,8 @@ namespace Umbraco.Core.Manifest ParameterEditors = parameterEditors.ToArray(), GridEditors = gridEditors.ToArray(), ContentApps = contentApps.ToArray(), - Dashboards = dashboards.ToArray() + Dashboards = dashboards.ToArray(), + Sections = sections.ToArray() }; } diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Core/Manifest/PackageManifest.cs index cd806ac847..b29a28ab06 100644 --- a/src/Umbraco.Core/Manifest/PackageManifest.cs +++ b/src/Umbraco.Core/Manifest/PackageManifest.cs @@ -1,6 +1,5 @@ using System; using Newtonsoft.Json; -using Umbraco.Core.Models.ContentEditing; using Umbraco.Core.PropertyEditors; namespace Umbraco.Core.Manifest @@ -10,25 +9,52 @@ namespace Umbraco.Core.Manifest /// public class PackageManifest { + /// + /// Gets or sets the scripts listed in the manifest. + /// [JsonProperty("javascript")] public string[] Scripts { get; set; } = Array.Empty(); + /// + /// Gets or sets the stylesheets listed in the manifest. + /// [JsonProperty("css")] - public string[] Stylesheets { get; set; }= Array.Empty(); + public string[] Stylesheets { get; set; } = Array.Empty(); + /// + /// Gets or sets the property editors listed in the manifest. + /// [JsonProperty("propertyEditors")] public IDataEditor[] PropertyEditors { get; set; } = Array.Empty(); + /// + /// Gets or sets the parameter editors listed in the manifest. + /// [JsonProperty("parameterEditors")] public IDataEditor[] ParameterEditors { get; set; } = Array.Empty(); + /// + /// Gets or sets the grid editors listed in the manifest. + /// [JsonProperty("gridEditors")] public GridEditor[] GridEditors { get; set; } = Array.Empty(); + /// + /// Gets or sets the content apps listed in the manifest. + /// [JsonProperty("contentApps")] public ManifestContentAppDefinition[] ContentApps { get; set; } = Array.Empty(); + /// + /// Gets or sets the dashboards listed in the manifest. + /// [JsonProperty("dashboards")] public ManifestDashboardDefinition[] Dashboards { get; set; } = Array.Empty(); + + /// + /// Gets or sets the sections listed in the manifest. + /// + [JsonProperty("sections")] + public ManifestBackOfficeSection[] Sections { get; set; } = Array.Empty(); } } diff --git a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs index 51935e6517..833955ee6a 100644 --- a/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Core/Migrations/Upgrade/UmbracoPlan.cs @@ -3,6 +3,7 @@ using System.Configuration; using Semver; using Umbraco.Core.Configuration; using Umbraco.Core.Migrations.Upgrade.V_7_12_0; +using Umbraco.Core.Migrations.Upgrade.V_7_14_0; using Umbraco.Core.Migrations.Upgrade.V_8_0_0; namespace Umbraco.Core.Migrations.Upgrade @@ -122,6 +123,7 @@ namespace Umbraco.Core.Migrations.Upgrade To("{C39BF2A7-1454-4047-BBFE-89E40F66ED63}"); To("{64EBCE53-E1F0-463A-B40B-E98EFCCA8AE2}"); To("{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}"); + To("{8A027815-D5CD-4872-8B88-9A51AB5986A6}"); // from 7.14.0 //FINAL @@ -145,12 +147,23 @@ namespace Umbraco.Core.Migrations.Upgrade // main chain, skipping the migrations // From("{init-7.12.0}"); - // start stop target + // clone start / clone stop / target ToWithClone("{init-7.10.0}", "{1350617A-4930-4D61-852F-E3AA9E692173}", "{BBD99901-1545-40E4-8A5A-D7A675C7D2F2}"); From("{init-7.12.1}").To("{init-7.10.0}"); // same as 7.12.0 From("{init-7.12.2}").To("{init-7.10.0}"); // same as 7.12.0 From("{init-7.12.3}").To("{init-7.10.0}"); // same as 7.12.0 + From("{init-7.12.4}").To("{init-7.10.0}"); // same as 7.12.0 + From("{init-7.13.0}").To("{init-7.10.0}"); // same as 7.12.0 + From("{init-7.13.1}").To("{init-7.10.0}"); // same as 7.12.0 + + // 7.14.0 has migrations, handle it... + // clone going from 7.10 to 1350617A (the last one before we started to merge 7.12 migrations), then + // clone going from CF51B39B (after 7.12 migrations) to 0009109C (the last one before we started to merge 7.12 migrations), + // ending in 8A027815 (after 7.14 migrations) + From("{init-7.14.0}") + .ToWithClone("{init-7.10.0}", "{1350617A-4930-4D61-852F-E3AA9E692173}", "{9109B8AF-6B34-46EE-9484-7434196D0C79}") + .ToWithClone("{CF51B39B-9B9A-4740-BB7C-EAF606A7BFBF}", "{0009109C-A0B8-4F3F-8FEB-C137BBDDA268}", "{8A027815-D5CD-4872-8B88-9A51AB5986A6}"); } } } diff --git a/src/Umbraco.Core/Migrations/Upgrade/V_7_14_0/UpdateMemberGroupPickerData.cs b/src/Umbraco.Core/Migrations/Upgrade/V_7_14_0/UpdateMemberGroupPickerData.cs new file mode 100644 index 0000000000..c70f42076f --- /dev/null +++ b/src/Umbraco.Core/Migrations/Upgrade/V_7_14_0/UpdateMemberGroupPickerData.cs @@ -0,0 +1,29 @@ +namespace Umbraco.Core.Migrations.Upgrade.V_7_14_0 +{ + /// + /// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268. + /// + public class UpdateMemberGroupPickerData : MigrationBase + { + /// + /// Migrates member group picker properties from NVarchar to NText. See https://github.com/umbraco/Umbraco-CMS/issues/3268. + /// + public UpdateMemberGroupPickerData(IMigrationContext context) + : base(context) + { } + + public override void Migrate() + { + Database.Execute($@"UPDATE umbracoPropertyData SET textValue = varcharValue, varcharValue = NULL + WHERE textValue IS NULL AND id IN ( + SELECT id FROM umbracoPropertyData WHERE propertyTypeId in ( + SELECT id from cmsPropertyType where dataTypeId IN ( + SELECT nodeId FROM umbracoDataType WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.MemberGroupPicker}' + ) + ) + )"); + + Database.Execute($"UPDATE umbracoDataType SET dbType = 'Ntext' WHERE propertyEditorAlias = '{Constants.PropertyEditors.Aliases.MemberGroupPicker}'"); + } + } +} diff --git a/src/Umbraco.Core/Models/ApplicationTree.cs b/src/Umbraco.Core/Models/ApplicationTree.cs deleted file mode 100644 index ccdebea724..0000000000 --- a/src/Umbraco.Core/Models/ApplicationTree.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Diagnostics; -using Umbraco.Core.Services; - -namespace Umbraco.Core.Models -{ - [DebuggerDisplay("Tree - {Title} ({ApplicationAlias})")] - public class ApplicationTree - { - private static readonly ConcurrentDictionary ResolvedTypes = new ConcurrentDictionary(); - - /// - /// Initializes a new instance of the class. - /// - public ApplicationTree() { } - - /// - /// Initializes a new instance of the class. - /// - /// if set to true [initialize]. - /// The sort order. - /// The application alias. - /// The tree alias. - /// The tree title. - /// The icon closed. - /// The icon opened. - /// The tree type. - public ApplicationTree(bool initialize, int sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type) - { - Initialize = initialize; - SortOrder = sortOrder; - ApplicationAlias = applicationAlias; - Alias = alias; - Title = title; - IconClosed = iconClosed; - IconOpened = iconOpened; - Type = type; - - } - - /// - /// Gets or sets a value indicating whether this should initialize. - /// - /// true if initialize; otherwise, false. - public bool Initialize { get; set; } - - /// - /// Gets or sets the sort order. - /// - /// The sort order. - public int SortOrder { get; set; } - - /// - /// Gets the application alias. - /// - /// The application alias. - public string ApplicationAlias { get; } - - /// - /// Gets the tree alias. - /// - /// The alias. - public string Alias { get; } - - /// - /// Gets or sets the tree title. - /// - /// The title. - public string Title { get; set; } - - /// - /// Gets or sets the icon closed. - /// - /// The icon closed. - public string IconClosed { get; set; } - - /// - /// Gets or sets the icon opened. - /// - /// The icon opened. - public string IconOpened { get; set; } - - /// - /// Gets or sets the tree type assembly name. - /// - /// The type. - public string Type { get; set; } - - /// - /// Returns the localized root node display name - /// - /// - /// - public string GetRootNodeDisplayName(ILocalizedTextService textService) - { - var label = $"[{Alias}]"; - - // try to look up a the localized tree header matching the tree alias - var localizedLabel = textService.Localize("treeHeaders/" + Alias); - - // if the localizedLabel returns [alias] then return the title attribute from the trees.config file, if it's defined - if (localizedLabel != null && localizedLabel.Equals(label, StringComparison.InvariantCultureIgnoreCase)) - { - if (string.IsNullOrEmpty(Title) == false) - label = Title; - } - else - { - // the localizedLabel translated into something that's not just [alias], so use the translation - label = localizedLabel; - } - - return label; - } - - private Type _runtimeType; - - /// - /// Returns the CLR type based on it's assembly name stored in the config - /// - /// - public Type GetRuntimeType() - { - return _runtimeType ?? (_runtimeType = System.Type.GetType(Type)); - } - - /// - /// Used to try to get and cache the tree type - /// - /// - /// - internal static Type TryGetType(string type) - { - try - { - return ResolvedTypes.GetOrAdd(type, s => - { - var result = System.Type.GetType(type); - if (result != null) - { - return result; - } - - //we need to implement a bit of a hack here due to some trees being renamed and backwards compat - var parts = type.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - if (parts.Length != 2) - throw new InvalidOperationException("Could not resolve type"); - if (parts[1].Trim() != "Umbraco.Web" || parts[0].StartsWith("Umbraco.Web.Trees") == false || parts[0].EndsWith("Controller")) - throw new InvalidOperationException("Could not resolve type"); - - //if it's one of our controllers but it's not suffixed with "Controller" then add it and try again - var tempType = parts[0] + "Controller, Umbraco.Web"; - - result = System.Type.GetType(tempType); - if (result != null) - return result; - - throw new InvalidOperationException("Could not resolve type"); - }); - } - catch (InvalidOperationException) - { - //swallow, this is our own exception, couldn't find the type - // fixme bad use of exceptions here! - return null; - } - } - } -} diff --git a/src/Umbraco.Core/Models/ITemplate.cs b/src/Umbraco.Core/Models/ITemplate.cs index 97b9324415..6548a49626 100644 --- a/src/Umbraco.Core/Models/ITemplate.cs +++ b/src/Umbraco.Core/Models/ITemplate.cs @@ -1,11 +1,9 @@ -using System; -using System.Runtime.Serialization; -using Umbraco.Core.Models.Entities; +using Umbraco.Core.Models.Entities; namespace Umbraco.Core.Models { /// - /// Defines a Template File (Masterpage or Mvc View) + /// Defines a Template File (Mvc View) /// public interface ITemplate : IFile, IRememberBeingDirty, ICanBeDirty { diff --git a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs b/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs index a852fcc997..f14fe47bfe 100644 --- a/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs +++ b/src/Umbraco.Core/Models/Packaging/CompiledPackage.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Models.Packaging public string Author { get; set; } public string AuthorUrl { get; set; } public string Readme { get; set; } - public string Control { get; set; } + public string PackageView { get; set; } public string IconUrl { get; set; } public string Actions { get; set; } //fixme: Should we make this strongly typed to IEnumerable ? diff --git a/src/Umbraco.Core/Models/Packaging/IPackageInfo.cs b/src/Umbraco.Core/Models/Packaging/IPackageInfo.cs index 8722ee7811..eea56549f1 100644 --- a/src/Umbraco.Core/Models/Packaging/IPackageInfo.cs +++ b/src/Umbraco.Core/Models/Packaging/IPackageInfo.cs @@ -13,7 +13,12 @@ namespace Umbraco.Core.Models.Packaging string Author { get; } string AuthorUrl { get; } string Readme { get; } - string Control { get; } //fixme - this needs to be an angular view + + /// + /// This is the angular view path that will be loaded when the package installs + /// + string PackageView { get; } + string IconUrl { get; } } } diff --git a/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs b/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs index c068c57b08..8c0ef79d0b 100644 --- a/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs +++ b/src/Umbraco.Core/Models/Packaging/PackageDefinition.cs @@ -25,7 +25,7 @@ namespace Umbraco.Core.Models.Packaging Actions = compiled.Actions, Author = compiled.Author, AuthorUrl = compiled.AuthorUrl, - Control = compiled.Control, + PackageView = compiled.PackageView, IconUrl = compiled.IconUrl, License = compiled.License, LicenseUrl = compiled.LicenseUrl, @@ -115,9 +115,9 @@ namespace Umbraco.Core.Models.Packaging [DataMember(Name = "files")] public IList Files { get; set; } = new List(); - //fixme: Change this to angular view - [DataMember(Name = "loadControl")] - public string Control { get; set; } = string.Empty; + /// + [DataMember(Name = "packageView")] + public string PackageView { get; set; } = string.Empty; [DataMember(Name = "actions")] public string Actions { get; set; } = ""; @@ -127,38 +127,7 @@ namespace Umbraco.Core.Models.Packaging [DataMember(Name = "iconUrl")] public string IconUrl { get; set; } = string.Empty; - - public PackageDefinition Clone() - { - return new PackageDefinition - { - Id = Id, - PackagePath = PackagePath, - Name = Name, - Files = new List(Files), - UmbracoVersion = (Version) UmbracoVersion.Clone(), - Version = Version, - Url = Url, - Readme = Readme, - AuthorUrl = AuthorUrl, - Author = Author, - LicenseUrl = LicenseUrl, - Actions = Actions, - PackageId = PackageId, - Control = Control, - DataTypes = new List(DataTypes), - IconUrl = IconUrl, - License = License, - Templates = new List(Templates), - Languages = new List(Languages), - Macros = new List(Macros), - Stylesheets = new List(Stylesheets), - DocumentTypes = new List(DocumentTypes), - DictionaryItems = new List(DictionaryItems), - ContentNodeId = ContentNodeId, - ContentLoadChildNodes = ContentLoadChildNodes - }; - } + } diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs index ee3fd62985..8be56850d1 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedModelFactory.cs @@ -68,7 +68,7 @@ namespace Umbraco.Core.Models.PublishedContent var typeName = attribute == null ? type.Name : attribute.ContentTypeAlias; if (modelInfos.TryGetValue(typeName, out var modelInfo)) - throw new InvalidOperationException($"Both types {type.FullName} and {modelInfo.ModelType.FullName} want to be a model type for content type with alias \"{typeName}\"."); + throw new InvalidOperationException($"Both types '{type.AssemblyQualifiedName}' and '{modelInfo.ModelType.AssemblyQualifiedName}' want to be a model type for content type with alias \"{typeName}\"."); // have to use an unsafe ctor because we don't know the types, really var modelCtor = ReflectionUtilities.EmitConstructorUnsafe>(constructor); diff --git a/src/Umbraco.Core/Models/Section.cs b/src/Umbraco.Core/Models/Section.cs deleted file mode 100644 index 4b7f8309dd..0000000000 --- a/src/Umbraco.Core/Models/Section.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Umbraco.Core.Models -{ - /// - /// Represents a section defined in the app.config file. - /// - public class Section - { - public Section(string name, string @alias, int sortOrder) - { - Name = name; - Alias = alias; - SortOrder = sortOrder; - } - - public Section() - { } - - public string Name { get; set; } - public string Alias { get; set; } - public int SortOrder { get; set; } - } -} diff --git a/src/Umbraco.Core/Models/Trees/IBackOfficeSection.cs b/src/Umbraco.Core/Models/Trees/IBackOfficeSection.cs new file mode 100644 index 0000000000..86e2a18fd5 --- /dev/null +++ b/src/Umbraco.Core/Models/Trees/IBackOfficeSection.cs @@ -0,0 +1,18 @@ +namespace Umbraco.Core.Models.Trees +{ + /// + /// Defines a back office section. + /// + public interface IBackOfficeSection + { + /// + /// Gets the alias of the section. + /// + string Alias { get; } + + /// + /// Gets the name of the section. + /// + string Name { get; } + } +} diff --git a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs index 0d533cfbc2..9e6339178e 100644 --- a/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs +++ b/src/Umbraco.Core/Packaging/CompiledPackageXmlParser.cs @@ -51,7 +51,7 @@ namespace Umbraco.Core.Packaging IconUrl = package.Element("iconUrl")?.Value, UmbracoVersion = new Version((int)requirements.Element("major"), (int)requirements.Element("minor"), (int)requirements.Element("patch")), UmbracoVersionRequirementsType = requirements.AttributeValue("type").IsNullOrWhiteSpace() ? RequirementsType.Legacy : Enum.Parse(requirements.AttributeValue("type"), true), - Control = package.Element("control")?.Value, + PackageView = xml.Root.Element("view")?.Value, Actions = xml.Root.Element("Actions")?.ToString(SaveOptions.None) ?? "", //take the entire outer xml value Files = xml.Root.Element("files")?.Elements("file")?.Select(CompiledPackageFile.Create).ToList() ?? new List(), Macros = xml.Root.Element("Macros")?.Elements("macro") ?? Enumerable.Empty(), diff --git a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs index 2e9fee9595..9bea527b91 100644 --- a/src/Umbraco.Core/Packaging/PackageDataInstallation.cs +++ b/src/Umbraco.Core/Packaging/PackageDataInstallation.cs @@ -1234,10 +1234,7 @@ namespace Umbraco.Core.Packaging var alias = templateElement.Element("Alias").Value; var design = templateElement.Element("Design").Value; var masterElement = templateElement.Element("Master"); - - var isMasterPage = IsMasterPageSyntax(design); - var path = isMasterPage ? MasterpagePath(alias) : ViewPath(alias); - + var existingTemplate = _fileService.GetTemplate(alias) as Template; var template = existingTemplate ?? new Template(templateName, alias); template.Content = design; @@ -1257,23 +1254,11 @@ namespace Umbraco.Core.Packaging return templates; } - - private bool IsMasterPageSyntax(string code) - { - return Regex.IsMatch(code, @"<%@\s*Master", RegexOptions.IgnoreCase) || - code.InvariantContains("("packageGuid"), IconUrl = xml.AttributeValue("iconUrl") ?? string.Empty, UmbracoVersion = xml.AttributeValue("umbVersion"), + PackageView = xml.AttributeValue("view") ?? string.Empty, License = xml.Element("license")?.Value ?? string.Empty, LicenseUrl = xml.Element("license")?.AttributeValue("url") ?? string.Empty, Author = xml.Element("author")?.Value ?? string.Empty, @@ -49,8 +50,7 @@ namespace Umbraco.Core.Packaging Languages = xml.Element("languages")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), DictionaryItems = xml.Element("dictionaryitems")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), DataTypes = xml.Element("datatypes")?.Value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList() ?? new List(), - Files = xml.Element("files")?.Elements("file").Select(x => x.Value).ToList() ?? new List(), - Control = xml.Element("loadcontrol")?.Value ?? string.Empty + Files = xml.Element("files")?.Elements("file").Select(x => x.Value).ToList() ?? new List() }; return retVal; @@ -77,6 +77,7 @@ namespace Umbraco.Core.Packaging new XAttribute("iconUrl", def.IconUrl ?? string.Empty), new XAttribute("umbVersion", def.UmbracoVersion), new XAttribute("packageGuid", def.PackageId), + new XAttribute("view", def.PackageView ?? string.Empty), new XElement("license", new XCData(def.License ?? string.Empty), @@ -100,8 +101,7 @@ namespace Umbraco.Core.Packaging new XElement("macros", string.Join(",", def.Macros ?? Array.Empty())), new XElement("files", (def.Files ?? Array.Empty()).Where(x => !x.IsNullOrWhiteSpace()).Select(x => new XElement("file", x))), new XElement("languages", string.Join(",", def.Languages ?? Array.Empty())), - new XElement("dictionaryitems", string.Join(",", def.DictionaryItems ?? Array.Empty())), - new XElement("loadcontrol", def.Control ?? string.Empty)); //fixme: no more loadcontrol, needs to be an angular view + new XElement("dictionaryitems", string.Join(",", def.DictionaryItems ?? Array.Empty()))); return packageXml; } diff --git a/src/Umbraco.Core/Packaging/PackagesRepository.cs b/src/Umbraco.Core/Packaging/PackagesRepository.cs index 249d02a320..1df232f62d 100644 --- a/src/Umbraco.Core/Packaging/PackagesRepository.cs +++ b/src/Umbraco.Core/Packaging/PackagesRepository.cs @@ -161,30 +161,30 @@ namespace Umbraco.Core.Packaging try { //Init package file - var packageManifest = CreatePackageManifest(out var manifestRoot, out var filesXml); + var compiledPackageXml = CreateCompiledPackageXml(out var root, out var filesXml); //Info section - manifestRoot.Add(GetPackageInfoXml(definition)); + root.Add(GetPackageInfoXml(definition)); - PackageDocumentsAndTags(definition, manifestRoot); - PackageDocumentTypes(definition, manifestRoot); - PackageTemplates(definition, manifestRoot); - PackageStylesheets(definition, manifestRoot); - PackageMacros(definition, manifestRoot, filesXml, temporaryPath); - PackageDictionaryItems(definition, manifestRoot); - PackageLanguages(definition, manifestRoot); - PackageDataTypes(definition, manifestRoot); + PackageDocumentsAndTags(definition, root); + PackageDocumentTypes(definition, root); + PackageTemplates(definition, root); + PackageStylesheets(definition, root); + PackageMacros(definition, root, filesXml, temporaryPath); + PackageDictionaryItems(definition, root); + PackageLanguages(definition, root); + PackageDataTypes(definition, root); //Files foreach (var fileName in definition.Files) - AppendFileToManifest(fileName, temporaryPath, filesXml); + AppendFileToPackage(fileName, temporaryPath, filesXml); - //Load control on install... - if (!string.IsNullOrEmpty(definition.Control)) + //Load view on install... + if (!string.IsNullOrEmpty(definition.PackageView)) { - var control = new XElement("control", definition.Control); - AppendFileToManifest(definition.Control, temporaryPath, filesXml); - manifestRoot.Add(control); + var control = new XElement("view", definition.PackageView); + AppendFileToPackage(definition.PackageView, temporaryPath, filesXml); + root.Add(control); } //Actions @@ -196,20 +196,20 @@ namespace Umbraco.Core.Packaging //this will be formatted like a full xml block like ... and we want the child nodes var parsed = XElement.Parse(definition.Actions); actionsXml.Add(parsed.Elements()); - manifestRoot.Add(actionsXml); + root.Add(actionsXml); } catch (Exception e) { - _logger.Warn(e, "Could not add package actions to the package manifest, the xml did not parse"); + _logger.Warn(e, "Could not add package actions to the package, the xml did not parse"); } } - var manifestFileName = temporaryPath + "/package.xml"; + var packageXmlFileName = temporaryPath + "/package.xml"; - if (File.Exists(manifestFileName)) - File.Delete(manifestFileName); + if (File.Exists(packageXmlFileName)) + File.Delete(packageXmlFileName); - packageManifest.Save(manifestFileName); + compiledPackageXml.Save(packageXmlFileName); // check if there's a packages directory below media @@ -242,7 +242,7 @@ namespace Umbraco.Core.Packaging throw new InvalidOperationException("Validation failed, there is invalid data on the model: " + string.Join(", ", results.Select(x => x.ErrorMessage))); } - private void PackageDataTypes(PackageDefinition definition, XContainer manifestRoot) + private void PackageDataTypes(PackageDefinition definition, XContainer root) { var dataTypes = new XElement("DataTypes"); foreach (var dtId in definition.DataTypes) @@ -252,10 +252,10 @@ namespace Umbraco.Core.Packaging if (dataType == null) continue; dataTypes.Add(_serializer.Serialize(dataType)); } - manifestRoot.Add(dataTypes); + root.Add(dataTypes); } - private void PackageLanguages(PackageDefinition definition, XContainer manifestRoot) + private void PackageLanguages(PackageDefinition definition, XContainer root) { var languages = new XElement("Languages"); foreach (var langId in definition.Languages) @@ -265,10 +265,10 @@ namespace Umbraco.Core.Packaging if (lang == null) continue; languages.Add(_serializer.Serialize(lang)); } - manifestRoot.Add(languages); + root.Add(languages); } - private void PackageDictionaryItems(PackageDefinition definition, XContainer manifestRoot) + private void PackageDictionaryItems(PackageDefinition definition, XContainer root) { var dictionaryItems = new XElement("DictionaryItems"); foreach (var dictionaryId in definition.DictionaryItems) @@ -278,10 +278,10 @@ namespace Umbraco.Core.Packaging if (di == null) continue; dictionaryItems.Add(_serializer.Serialize(di, false)); } - manifestRoot.Add(dictionaryItems); + root.Add(dictionaryItems); } - private void PackageMacros(PackageDefinition definition, XContainer manifestRoot, XContainer filesXml, string temporaryPath) + private void PackageMacros(PackageDefinition definition, XContainer root, XContainer filesXml, string temporaryPath) { var macros = new XElement("Macros"); foreach (var macroId in definition.Macros) @@ -291,14 +291,14 @@ namespace Umbraco.Core.Packaging var macroXml = GetMacroXml(outInt, out var macro); if (macroXml == null) continue; macros.Add(macroXml); - //if the macro has a file copy it to the manifest + //if the macro has a file copy it to the xml if (!string.IsNullOrEmpty(macro.MacroSource)) - AppendFileToManifest(macro.MacroSource, temporaryPath, filesXml); + AppendFileToPackage(macro.MacroSource, temporaryPath, filesXml); } - manifestRoot.Add(macros); + root.Add(macros); } - private void PackageStylesheets(PackageDefinition definition, XContainer manifestRoot) + private void PackageStylesheets(PackageDefinition definition, XContainer root) { var stylesheetsXml = new XElement("Stylesheets"); foreach (var stylesheetName in definition.Stylesheets) @@ -308,10 +308,10 @@ namespace Umbraco.Core.Packaging if (xml != null) stylesheetsXml.Add(xml); } - manifestRoot.Add(stylesheetsXml); + root.Add(stylesheetsXml); } - private void PackageTemplates(PackageDefinition definition, XContainer manifestRoot) + private void PackageTemplates(PackageDefinition definition, XContainer root) { var templatesXml = new XElement("Templates"); foreach (var templateId in definition.Templates) @@ -321,10 +321,10 @@ namespace Umbraco.Core.Packaging if (template == null) continue; templatesXml.Add(_serializer.Serialize(template)); } - manifestRoot.Add(templatesXml); + root.Add(templatesXml); } - private void PackageDocumentTypes(PackageDefinition definition, XContainer manifestRoot) + private void PackageDocumentTypes(PackageDefinition definition, XContainer root) { var contentTypes = new HashSet(); var docTypesXml = new XElement("DocumentTypes"); @@ -338,10 +338,10 @@ namespace Umbraco.Core.Packaging foreach (var contentType in contentTypes) docTypesXml.Add(_serializer.Serialize(contentType)); - manifestRoot.Add(docTypesXml); + root.Add(docTypesXml); } - private void PackageDocumentsAndTags(PackageDefinition definition, XContainer manifestRoot) + private void PackageDocumentsAndTags(PackageDefinition definition, XContainer root) { //Documents and tags if (string.IsNullOrEmpty(definition.ContentNodeId) == false && int.TryParse(definition.ContentNodeId, out var contentNodeId)) @@ -356,7 +356,7 @@ namespace Umbraco.Core.Packaging //Create the Documents/DocumentSet node - manifestRoot.Add( + root.Add( new XElement("Documents", new XElement("DocumentSet", new XAttribute("importMode", "root"), @@ -438,12 +438,12 @@ namespace Umbraco.Core.Packaging } /// - /// Appends a file to package manifest and copies the file to the correct folder. + /// Appends a file to package and copies the file to the correct folder. /// /// The path. /// The package directory. /// The files xml node - private static void AppendFileToManifest(string path, string packageDirectory, XContainer filesXml) + private static void AppendFileToPackage(string path, string packageDirectory, XContainer filesXml) { if (!path.StartsWith("~/") && !path.StartsWith("/")) path = "~/" + path; @@ -584,12 +584,12 @@ namespace Umbraco.Core.Packaging return info; } - private static XDocument CreatePackageManifest(out XElement root, out XElement files) + private static XDocument CreateCompiledPackageXml(out XElement root, out XElement files) { files = new XElement("files"); root = new XElement("umbPackage", files); - var packageManifest = new XDocument(root); - return packageManifest; + var compiledPackageXml = new XDocument(root); + return compiledPackageXml; } private XDocument EnsureStorage(out string packagesFile) diff --git a/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs index 4bab445bee..2e9bdcfc4a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ITemplateRepository.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; +using System.Collections.Generic; using System.IO; using Umbraco.Core.Models; @@ -18,21 +16,6 @@ namespace Umbraco.Core.Persistence.Repositories IEnumerable GetDescendants(int masterTemplateId); IEnumerable GetDescendants(string alias); - /// - /// This checks what the default rendering engine is set in config but then also ensures that there isn't already - /// a template that exists in the opposite rendering engine's template folder, then returns the appropriate - /// rendering engine to use. - /// - /// - /// - /// The reason this is required is because for example, if you have a master page file already existing under ~/masterpages/Blah.aspx - /// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml - /// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page. - /// This is mostly related to installing packages since packages install file templates to the file system and then create the - /// templates in business logic. Without this, it could cause the wrong rendering engine to be used for a package. - /// - RenderingEngine DetermineTemplateRenderingEngine(ITemplate template); - /// /// Validates a /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs index 19ef303ebe..ac0f4f0bed 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/TemplateRepository.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using NPoco; using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -23,20 +22,14 @@ namespace Umbraco.Core.Persistence.Repositories.Implement /// internal class TemplateRepository : NPocoRepositoryBase, ITemplateRepository { - private readonly IFileSystem _masterpagesFileSystem; private readonly IFileSystem _viewsFileSystem; - private readonly ITemplatesSection _templateConfig; private readonly ViewHelper _viewHelper; - private readonly MasterPageHelper _masterPageHelper; - public TemplateRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger, ITemplatesSection templateConfig, IFileSystems fileSystems) + public TemplateRepository(IScopeAccessor scopeAccessor, CacheHelper cache, ILogger logger, IFileSystems fileSystems) : base(scopeAccessor, cache, logger) { - _masterpagesFileSystem = fileSystems.MasterPagesFileSystem; _viewsFileSystem = fileSystems.MvcViewsFileSystem; - _templateConfig = templateConfig; _viewHelper = new ViewHelper(_viewsFileSystem); - _masterPageHelper = new MasterPageHelper(_masterpagesFileSystem); } protected override IRepositoryCachePolicy CreateCachePolicy() @@ -255,18 +248,9 @@ namespace Umbraco.Core.Persistence.Repositories.Implement else { // else, create or write template.Content to disk - if (DetermineTemplateRenderingEngine(template) == RenderingEngine.Mvc) - { - content = originalAlias == null - ? _viewHelper.CreateView(template, true) - : _viewHelper.UpdateViewFile(template, originalAlias); - } - else - { - content = originalAlias == null - ? _masterPageHelper.CreateMasterPage(template, this, true) - : _masterPageHelper.UpdateMasterPageFile(template, originalAlias, this); - } + content = originalAlias == null + ? _viewHelper.CreateView(template, true) + : _viewHelper.UpdateViewFile(template, originalAlias); } // once content has been set, "template on disk" are not "on disk" anymore @@ -298,16 +282,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement Database.Execute(delete, new { id = GetEntityId(entity) }); } - if (DetermineTemplateRenderingEngine(entity) == RenderingEngine.Mvc) - { - var viewName = string.Concat(entity.Alias, ".cshtml"); - _viewsFileSystem.DeleteFile(viewName); - } - else - { - var masterpageName = string.Concat(entity.Alias, ".master"); - _masterpagesFileSystem.DeleteFile(masterpageName); - } + var viewName = string.Concat(entity.Alias, ".cshtml"); + _viewsFileSystem.DeleteFile(viewName); entity.DeleteDate = DateTime.Now; } @@ -388,27 +364,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement template.VirtualPath = _viewsFileSystem.GetUrl(path); return; } - path = string.Concat(template.Alias, ".master"); - if (_masterpagesFileSystem.FileExists(path)) - { - template.VirtualPath = _masterpagesFileSystem.GetUrl(path); - return; - } } else { // we know the path already - var ext = Path.GetExtension(path); - switch (ext) - { - case ".cshtml": - case ".vbhtml": - template.VirtualPath = _viewsFileSystem.GetUrl(path); - return; - case ".master": - template.VirtualPath = _masterpagesFileSystem.GetUrl(path); - return; - } + template.VirtualPath = _viewsFileSystem.GetUrl(path); } template.VirtualPath = string.Empty; // file not found... @@ -426,25 +386,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement path = string.Concat(template.Alias, ".vbhtml"); if (_viewsFileSystem.FileExists(path)) return GetFileContent(template, _viewsFileSystem, path, init); - path = string.Concat(template.Alias, ".master"); - if (_masterpagesFileSystem.FileExists(path)) - return GetFileContent(template, _masterpagesFileSystem, path, init); } else { // we know the path already - var ext = Path.GetExtension(path); - switch (ext) - { - case ".cshtml": - case ".vbhtml": - return GetFileContent(template, _viewsFileSystem, path, init); - case ".master": - return GetFileContent(template, _masterpagesFileSystem, path, init); - } + return GetFileContent(template, _viewsFileSystem, path, init); } template.VirtualPath = string.Empty; // file not found... + return string.Empty; } @@ -514,9 +464,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement case ".vbhtml": fs = _viewsFileSystem; break; - case ".master": - fs = _masterpagesFileSystem; - break; default: throw new Exception("Unsupported extension " + ext + "."); } @@ -625,56 +572,6 @@ namespace Umbraco.Core.Persistence.Repositories.Implement } } - /// - /// This checks what the default rendering engine is set in config but then also ensures that there isn't already - /// a template that exists in the opposite rendering engine's template folder, then returns the appropriate - /// rendering engine to use. - /// - /// - /// - /// The reason this is required is because for example, if you have a master page file already existing under ~/masterpages/Blah.aspx - /// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml - /// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page. - /// This is mostly related to installing packages since packages install file templates to the file system and then create the - /// templates in business logic. Without this, it could cause the wrong rendering engine to be used for a package. - /// - public RenderingEngine DetermineTemplateRenderingEngine(ITemplate template) - { - var engine = _templateConfig.DefaultRenderingEngine; - var viewHelper = new ViewHelper(_viewsFileSystem); - if (viewHelper.ViewExists(template) == false) - { - if (template.Content.IsNullOrWhiteSpace() == false && MasterPageHelper.IsMasterPageSyntax(template.Content)) - { - //there is a design but its definitely a webforms design and we haven't got a MVC view already for it - return RenderingEngine.WebForms; - } - } - - var masterPageHelper = new MasterPageHelper(_masterpagesFileSystem); - - switch (engine) - { - case RenderingEngine.Mvc: - //check if there's a view in ~/masterpages - if (masterPageHelper.MasterPageExists(template) && viewHelper.ViewExists(template) == false) - { - //change this to webforms since there's already a file there for this template alias - engine = RenderingEngine.WebForms; - } - break; - case RenderingEngine.WebForms: - //check if there's a view in ~/views - if (viewHelper.ViewExists(template) && masterPageHelper.MasterPageExists(template) == false) - { - //change this to mvc since there's already a file there for this template alias - engine = RenderingEngine.Mvc; - } - break; - } - return engine; - } - /// /// Validates a /// @@ -689,21 +586,12 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var path = template.VirtualPath; // get valid paths - var validDirs = _templateConfig.DefaultRenderingEngine == RenderingEngine.Mvc - ? new[] { SystemDirectories.Masterpages, SystemDirectories.MvcViews } - : new[] { SystemDirectories.Masterpages }; + var validDirs = new[] { SystemDirectories.MvcViews }; // get valid extensions var validExts = new List(); - if (_templateConfig.DefaultRenderingEngine == RenderingEngine.Mvc) - { - validExts.Add("cshtml"); - validExts.Add("vbhtml"); - } - else - { - validExts.Add("master"); - } + validExts.Add("cshtml"); + validExts.Add("vbhtml"); // validate path and extension var validFile = IOHelper.VerifyEditPath(path, validDirs); diff --git a/src/Umbraco.Core/Services/IApplicationTreeService.cs b/src/Umbraco.Core/Services/IApplicationTreeService.cs deleted file mode 100644 index 691a3a0b63..0000000000 --- a/src/Umbraco.Core/Services/IApplicationTreeService.cs +++ /dev/null @@ -1,152 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Umbraco.Core.Models; - -namespace Umbraco.Core.Services -{ - public interface IApplicationTreeService - { - /// - /// Creates a new application tree. - /// - /// if set to true [initialize]. - /// The sort order. - /// The application alias. - /// The alias. - /// The title. - /// The icon closed. - /// The icon opened. - /// The type. - void MakeNew(bool initialize, int sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type); - - /// - /// Saves this instance. - /// - void SaveTree(ApplicationTree tree); - - /// - /// Deletes this instance. - /// - void DeleteTree(ApplicationTree tree); - - /// - /// Gets an ApplicationTree by it's tree alias. - /// - /// The tree alias. - /// An ApplicationTree instance - ApplicationTree GetByAlias(string treeAlias); - - /// - /// Gets all applicationTrees registered in umbraco from the umbracoAppTree table.. - /// - /// Returns a ApplicationTree Array - IEnumerable GetAll(); - - /// - /// Gets the application tree for the applcation with the specified alias - /// - /// The application alias. - /// Returns a ApplicationTree Array - IEnumerable GetApplicationTrees(string applicationAlias); - - /// - /// Gets the application tree for the applcation with the specified alias - /// - /// The application alias. - /// - /// Returns a ApplicationTree Array - IEnumerable GetApplicationTrees(string applicationAlias, bool onlyInitialized); - - /// - /// Gets the grouped application trees for the application with the specified alias - /// - /// - /// - /// - IDictionary> GetGroupedApplicationTrees(string applicationAlias, bool onlyInitialized); - } - - /// - /// Purely used to allow a service context to create the default services - /// - internal class EmptyApplicationTreeService : IApplicationTreeService - { - /// - /// Creates a new application tree. - /// - /// if set to true [initialize]. - /// The sort order. - /// The application alias. - /// The alias. - /// The title. - /// The icon closed. - /// The icon opened. - /// The type. - public void MakeNew(bool initialize, int sortOrder, string applicationAlias, string alias, string title, string iconClosed, string iconOpened, string type) - { - throw new System.NotImplementedException(); - } - - /// - /// Saves this instance. - /// - public void SaveTree(ApplicationTree tree) - { - throw new System.NotImplementedException(); - } - - /// - /// Deletes this instance. - /// - public void DeleteTree(ApplicationTree tree) - { - throw new System.NotImplementedException(); - } - - /// - /// Gets an ApplicationTree by it's tree alias. - /// - /// The tree alias. - /// An ApplicationTree instance - public ApplicationTree GetByAlias(string treeAlias) - { - throw new System.NotImplementedException(); - } - - /// - /// Gets all applicationTrees registered in umbraco from the umbracoAppTree table.. - /// - /// Returns a ApplicationTree Array - public IEnumerable GetAll() - { - throw new System.NotImplementedException(); - } - - public IDictionary> GetGroupedApplicationTrees(string applicationAlias, bool onlyInitialized) - { - throw new System.NotImplementedException(); - } - - /// - /// Gets the application tree for the applcation with the specified alias - /// - /// The application alias. - /// Returns a ApplicationTree Array - public IEnumerable GetApplicationTrees(string applicationAlias) - { - throw new System.NotImplementedException(); - } - - /// - /// Gets the application tree for the applcation with the specified alias - /// - /// The application alias. - /// - /// Returns a ApplicationTree Array - public IEnumerable GetApplicationTrees(string applicationAlias, bool onlyInitialized) - { - throw new System.NotImplementedException(); - } - } -} diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs index 76e850beb2..daf5d9b80c 100644 --- a/src/Umbraco.Core/Services/IFileService.cs +++ b/src/Umbraco.Core/Services/IFileService.cs @@ -210,21 +210,6 @@ namespace Umbraco.Core.Services /// Optional id of the user void SaveTemplate(IEnumerable templates, int userId = 0); - /// - /// This checks what the default rendering engine is set in config but then also ensures that there isn't already - /// a template that exists in the opposite rendering engine's template folder, then returns the appropriate - /// rendering engine to use. - /// - /// - /// - /// The reason this is required is because for example, if you have a master page file already existing under ~/masterpages/Blah.aspx - /// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml - /// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page. - /// This is mostly related to installing packages since packages install file templates to the file system and then create the - /// templates in business logic. Without this, it could cause the wrong rendering engine to be used for a package. - /// - RenderingEngine DetermineTemplateRenderingEngine(ITemplate template); - /// /// Gets the content of a template as a stream. /// diff --git a/src/Umbraco.Core/Services/ISectionService.cs b/src/Umbraco.Core/Services/ISectionService.cs deleted file mode 100644 index 899ae78245..0000000000 --- a/src/Umbraco.Core/Services/ISectionService.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Collections.Generic; -using Umbraco.Core.Models; - -namespace Umbraco.Core.Services -{ - public interface ISectionService - { - /// - /// The cache storage for all applications - /// - IEnumerable
GetSections(); - - /// - /// Get the user group's allowed sections - /// - /// - /// - IEnumerable
GetAllowedSections(int userId); - - /// - /// Gets the application by its alias. - /// - /// The application alias. - /// - Section GetByAlias(string appAlias); - - /// - /// Creates a new applcation if no application with the specified alias is found. - /// - /// The application name. - /// The application alias. - /// The application icon, which has to be located in umbraco/images/tray folder. - void MakeNew(string name, string alias, string icon); - - /// - /// Makes the new. - /// - /// The name. - /// The alias. - /// The icon. - /// The sort order. - void MakeNew(string name, string alias, string icon, int sortOrder); - - /// - /// Deletes the section - /// - void DeleteSection(Section section); - } - - /// - /// Purely used to allow a service context to create the default services - /// - internal class EmptySectionService : ISectionService - { - /// - /// The cache storage for all applications - /// - public IEnumerable
GetSections() - { - throw new System.NotImplementedException(); - } - - /// - /// Get the user's allowed sections - /// - /// - /// - public IEnumerable
GetAllowedSections(int userId) - { - throw new System.NotImplementedException(); - } - - /// - /// Gets the application by its alias. - /// - /// The application alias. - /// - public Section GetByAlias(string appAlias) - { - throw new System.NotImplementedException(); - } - - /// - /// Creates a new applcation if no application with the specified alias is found. - /// - /// The application name. - /// The application alias. - /// The application icon, which has to be located in umbraco/images/tray folder. - public void MakeNew(string name, string alias, string icon) - { - throw new System.NotImplementedException(); - } - - /// - /// Makes the new. - /// - /// The name. - /// The alias. - /// The icon. - /// The sort order. - public void MakeNew(string name, string alias, string icon, int sortOrder) - { - throw new System.NotImplementedException(); - } - - /// - /// Deletes the section - /// - public void DeleteSection(Section section) - { - throw new System.NotImplementedException(); - } - } -} diff --git a/src/Umbraco.Core/Services/Implement/FileService.cs b/src/Umbraco.Core/Services/Implement/FileService.cs index f15f0d7d47..0c08404ab3 100644 --- a/src/Umbraco.Core/Services/Implement/FileService.cs +++ b/src/Umbraco.Core/Services/Implement/FileService.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.IO; using System.Linq; using System.Text.RegularExpressions; @@ -556,27 +555,6 @@ namespace Umbraco.Core.Services.Implement } } - /// - /// This checks what the default rendering engine is set in config but then also ensures that there isn't already - /// a template that exists in the opposite rendering engine's template folder, then returns the appropriate - /// rendering engine to use. - /// - /// - /// - /// The reason this is required is because for example, if you have a master page file already existing under ~/masterpages/Blah.aspx - /// and then you go to create a template in the tree called Blah and the default rendering engine is MVC, it will create a Blah.cshtml - /// empty template in ~/Views. This means every page that is using Blah will go to MVC and render an empty page. - /// This is mostly related to installing packages since packages install file templates to the file system and then create the - /// templates in business logic. Without this, it could cause the wrong rendering engine to be used for a package. - /// - public RenderingEngine DetermineTemplateRenderingEngine(ITemplate template) - { - using (var scope = ScopeProvider.CreateScope(autoComplete: true)) - { - return _templateRepository.DetermineTemplateRenderingEngine(template); - } - } - /// /// Deletes a template by its alias /// @@ -1043,7 +1021,7 @@ namespace Umbraco.Core.Services.Implement _auditRepository.Save(new AuditItem(objectId, type, userId, entityType)); } - //TODO Method to change name and/or alias of view/masterpage template + //TODO Method to change name and/or alias of view template #region Event Handlers diff --git a/src/Umbraco.Core/Services/ServiceContext.cs b/src/Umbraco.Core/Services/ServiceContext.cs index 731d3a58c6..6d7ac8a5e7 100644 --- a/src/Umbraco.Core/Services/ServiceContext.cs +++ b/src/Umbraco.Core/Services/ServiceContext.cs @@ -25,8 +25,6 @@ namespace Umbraco.Core.Services private readonly Lazy _serverRegistrationService; private readonly Lazy _entityService; private readonly Lazy _relationService; - private readonly Lazy _treeService; - private readonly Lazy _sectionService; private readonly Lazy _macroService; private readonly Lazy _memberTypeService; private readonly Lazy _memberGroupService; @@ -38,7 +36,7 @@ namespace Umbraco.Core.Services /// /// Initializes a new instance of the class with lazy services. /// - public ServiceContext(Lazy publicAccessService, Lazy domainService, Lazy auditService, Lazy localizedTextService, Lazy tagService, Lazy contentService, Lazy userService, Lazy memberService, Lazy mediaService, Lazy contentTypeService, Lazy mediaTypeService, Lazy dataTypeService, Lazy fileService, Lazy localizationService, Lazy packagingService, Lazy serverRegistrationService, Lazy entityService, Lazy relationService, Lazy treeService, Lazy sectionService, Lazy macroService, Lazy memberTypeService, Lazy memberGroupService, Lazy notificationService, Lazy externalLoginService, Lazy redirectUrlService, Lazy consentService) + public ServiceContext(Lazy publicAccessService, Lazy domainService, Lazy auditService, Lazy localizedTextService, Lazy tagService, Lazy contentService, Lazy userService, Lazy memberService, Lazy mediaService, Lazy contentTypeService, Lazy mediaTypeService, Lazy dataTypeService, Lazy fileService, Lazy localizationService, Lazy packagingService, Lazy serverRegistrationService, Lazy entityService, Lazy relationService, Lazy macroService, Lazy memberTypeService, Lazy memberGroupService, Lazy notificationService, Lazy externalLoginService, Lazy redirectUrlService, Lazy consentService) { _publicAccessService = publicAccessService; _domainService = domainService; @@ -58,8 +56,6 @@ namespace Umbraco.Core.Services _serverRegistrationService = serverRegistrationService; _entityService = entityService; _relationService = relationService; - _treeService = treeService; - _sectionService = sectionService; _macroService = macroService; _memberTypeService = memberTypeService; _memberGroupService = memberGroupService; @@ -90,8 +86,6 @@ namespace Umbraco.Core.Services IMemberTypeService memberTypeService = null, IMemberService memberService = null, IUserService userService = null, - ISectionService sectionService = null, - IApplicationTreeService treeService = null, ITagService tagService = null, INotificationService notificationService = null, ILocalizedTextService localizedTextService = null, @@ -125,8 +119,6 @@ namespace Umbraco.Core.Services Lazy(serverRegistrationService), Lazy(entityService), Lazy(relationService), - Lazy(treeService), - Lazy(sectionService), Lazy(macroService), Lazy(memberTypeService), Lazy(memberGroupService), @@ -236,16 +228,6 @@ namespace Umbraco.Core.Services /// public IMemberService MemberService => _memberService.Value; - /// - /// Gets the - /// - public ISectionService SectionService => _sectionService.Value; - - /// - /// Gets the - /// - public IApplicationTreeService ApplicationTreeService => _treeService.Value; - /// /// Gets the MemberTypeService /// diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index 90fc472e30..b6a1103097 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -892,7 +892,7 @@ namespace Umbraco.Core } /// - /// Ensures that the folder path ends with a DirectorySeperatorChar + /// Ensures that the folder path ends with a DirectorySeparatorChar /// /// /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 2236854351..94f422e027 100755 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -291,7 +291,6 @@ - @@ -304,7 +303,6 @@ - @@ -355,6 +353,7 @@ + @@ -367,6 +366,7 @@ + @@ -448,6 +448,7 @@ + @@ -630,7 +631,6 @@ - @@ -678,7 +678,6 @@ - @@ -875,7 +874,6 @@ - @@ -1390,7 +1388,6 @@ - @@ -1420,7 +1417,6 @@ - diff --git a/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs b/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs index 50b27da89f..3532a11c63 100644 --- a/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs +++ b/src/Umbraco.Tests/Cache/DistributedCacheBinderTests.cs @@ -47,13 +47,6 @@ namespace Umbraco.Tests.Cache //Permission.Deleted += PermissionDeleted; //PermissionRepository.AssignedPermissions += CacheRefresherEventHandler_AssignedPermissions; - new EventDefinition(null, serviceContext.ApplicationTreeService, new EventArgs(), "Deleted"), - new EventDefinition(null, serviceContext.ApplicationTreeService, new EventArgs(), "Updated"), - new EventDefinition(null, serviceContext.ApplicationTreeService, new EventArgs(), "New"), - - new EventDefinition(null, serviceContext.SectionService, new EventArgs(), "Deleted"), - new EventDefinition(null, serviceContext.SectionService, new EventArgs(), "New"), - new EventDefinition>(null, serviceContext.UserService, new SaveEventArgs(Enumerable.Empty())), new EventDefinition>(null, serviceContext.UserService, new DeleteEventArgs(Enumerable.Empty())), new EventDefinition>(null, serviceContext.UserService, new SaveEventArgs(Enumerable.Empty())), diff --git a/src/Umbraco.Tests/Composing/TypeFinderTests.cs b/src/Umbraco.Tests/Composing/TypeFinderTests.cs index 49c807b19f..2b9474310b 100644 --- a/src/Umbraco.Tests/Composing/TypeFinderTests.cs +++ b/src/Umbraco.Tests/Composing/TypeFinderTests.cs @@ -90,7 +90,7 @@ namespace Umbraco.Tests.Composing Assert.AreEqual(0, typesFound.Count()); // 0 classes in _assemblies are marked with [Tree] typesFound = TypeFinder.FindClassesWithAttribute(new[] { typeof (UmbracoContext).Assembly }); - Assert.AreEqual(22, typesFound.Count()); // + classes in Umbraco.Web are marked with [Tree] + Assert.AreEqual(21, typesFound.Count()); // + classes in Umbraco.Web are marked with [Tree] } private static IProfilingLogger GetTestProfilingLogger() diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/TemplateElementDefaultTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/TemplateElementDefaultTests.cs deleted file mode 100644 index 4f7e8c1800..0000000000 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/TemplateElementDefaultTests.cs +++ /dev/null @@ -1,13 +0,0 @@ -using NUnit.Framework; - -namespace Umbraco.Tests.Configurations.UmbracoSettings -{ - [TestFixture] - public class TemplateElementDefaultTests : TemplateElementTests - { - protected override bool TestingDefaults - { - get { return true; } - } - } -} diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/TemplateElementTests.cs b/src/Umbraco.Tests/Configurations/UmbracoSettings/TemplateElementTests.cs deleted file mode 100644 index a2edf94ab5..0000000000 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/TemplateElementTests.cs +++ /dev/null @@ -1,16 +0,0 @@ -using NUnit.Framework; -using Umbraco.Core; - -namespace Umbraco.Tests.Configurations.UmbracoSettings -{ - [TestFixture] - public class TemplateElementTests : UmbracoSettingsTests - { - [Test] - public void DefaultRenderingEngine() - { - Assert.IsTrue(SettingsSection.Templates.DefaultRenderingEngine == RenderingEngine.Mvc); - } - - } -} diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config index 4c64485503..dd44e23328 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.config @@ -145,10 +145,6 @@ - - Mvc - - false true diff --git a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config index 21dfa1f19e..bee7133051 100644 --- a/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config +++ b/src/Umbraco.Tests/Configurations/UmbracoSettings/umbracoSettings.minimal.config @@ -37,11 +37,6 @@ - - - Mvc - - diff --git a/src/Umbraco.Tests/IO/IoHelperTests.cs b/src/Umbraco.Tests/IO/IoHelperTests.cs index b2ef5e4d31..b0e59cbb55 100644 --- a/src/Umbraco.Tests/IO/IoHelperTests.cs +++ b/src/Umbraco.Tests/IO/IoHelperTests.cs @@ -37,7 +37,6 @@ namespace Umbraco.Tests.IO Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Css, true), IOHelper.MapPath(SystemDirectories.Css, false)); Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Data, true), IOHelper.MapPath(SystemDirectories.Data, false)); Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Install, true), IOHelper.MapPath(SystemDirectories.Install, false)); - Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Masterpages, true), IOHelper.MapPath(SystemDirectories.Masterpages, false)); Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Media, true), IOHelper.MapPath(SystemDirectories.Media, false)); Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Packages, true), IOHelper.MapPath(SystemDirectories.Packages, false)); Assert.AreEqual(IOHelper.MapPath(SystemDirectories.Preview, true), IOHelper.MapPath(SystemDirectories.Preview, false)); diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs index ce3d1d705c..e77b9a6e10 100644 --- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs +++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs @@ -429,5 +429,21 @@ javascript: ['~/test.js',/*** some note about stuff asd09823-4**09234*/ '~/test2 Assert.AreEqual(1, db1.Sections.Length); Assert.AreEqual("forms", db1.Sections[0]); } + + [Test] + public void CanParseManifest_Sections() + { + const string json = @"{'sections': [ + { ""alias"": ""content"", ""name"": ""Content"" }, + { ""alias"": ""hello"", ""name"": ""World"" } +]}"; + + var manifest = _parser.ParseManifest(json); + Assert.AreEqual(2, manifest.Sections.Length); + Assert.AreEqual("content", manifest.Sections[0].Alias); + Assert.AreEqual("hello", manifest.Sections[1].Alias); + Assert.AreEqual("Content", manifest.Sections[0].Name); + Assert.AreEqual("World", manifest.Sections[1].Name); + } } } diff --git a/src/Umbraco.Tests/Packaging/Packages/Document_Type_Picker_1.1.zip b/src/Umbraco.Tests/Packaging/Packages/Document_Type_Picker_1.1.zip new file mode 100644 index 0000000000..18449bd373 Binary files /dev/null and b/src/Umbraco.Tests/Packaging/Packages/Document_Type_Picker_1.1.zip differ diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs index aeaf76967f..f3af1cf73f 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -7,12 +7,9 @@ using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; using Umbraco.Core.Models; -using Umbraco.Core.Models.Entities; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Dtos; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; @@ -36,7 +33,7 @@ namespace Umbraco.Tests.Persistence.Repositories private DocumentRepository CreateRepository(IScopeAccessor scopeAccessor, out ContentTypeRepository contentTypeRepository) { var cacheHelper = CacheHelper.Disabled; - var templateRepository = new TemplateRepository(scopeAccessor, cacheHelper, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepository = new TemplateRepository(scopeAccessor, cacheHelper, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(scopeAccessor, cacheHelper, Logger); contentTypeRepository = new ContentTypeRepository(scopeAccessor, cacheHelper, Logger, templateRepository); var languageRepository = new LanguageRepository(scopeAccessor, cacheHelper, Logger); @@ -46,7 +43,7 @@ namespace Umbraco.Tests.Persistence.Repositories private ContentTypeRepository CreateRepository(IScopeAccessor scopeAccessor) { - var templateRepository = new TemplateRepository(scopeAccessor, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepository = new TemplateRepository(scopeAccessor, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var contentTypeRepository = new ContentTypeRepository(scopeAccessor, CacheHelper.Disabled, Logger, templateRepository); return contentTypeRepository; } @@ -71,7 +68,7 @@ namespace Umbraco.Tests.Persistence.Repositories var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) { - var templateRepo = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepo = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var repository = CreateRepository((IScopeAccessor) provider); var templates = new[] { diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs index c1fa5381ff..2619827705 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs @@ -64,7 +64,7 @@ namespace Umbraco.Tests.Persistence.Repositories { cacheHelper = cacheHelper ?? CacheHelper; - templateRepository = new TemplateRepository(scopeAccessor, cacheHelper, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + templateRepository = new TemplateRepository(scopeAccessor, cacheHelper, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(scopeAccessor, cacheHelper, Logger); contentTypeRepository = new ContentTypeRepository(scopeAccessor, cacheHelper, Logger, templateRepository); var languageRepository = new LanguageRepository(scopeAccessor, cacheHelper, Logger); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs index a5402f964e..5511114d3e 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DomainRepositoryTest.cs @@ -4,9 +4,7 @@ using System.Linq; using Moq; using NUnit.Framework; using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; @@ -22,7 +20,7 @@ namespace Umbraco.Tests.Persistence.Repositories private DomainRepository CreateRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository, out DocumentRepository documentRepository, out LanguageRepository languageRepository) { var accessor = (IScopeAccessor) provider; - var templateRepository = new TemplateRepository(accessor, Core.Cache.CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepository = new TemplateRepository(accessor, Core.Cache.CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, Core.Cache.CacheHelper.Disabled, Logger); contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.CacheHelper.Disabled, Logger, templateRepository); languageRepository = new LanguageRepository(accessor, Core.Cache.CacheHelper.Disabled, Logger); diff --git a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs index e76d794e69..23d95163d0 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/PublicAccessRepositoryTest.cs @@ -4,10 +4,8 @@ using System.Linq; using Moq; using NUnit.Framework; using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Persistence; -using Umbraco.Core.Persistence.Repositories; using Umbraco.Core.Persistence.Repositories.Implement; using Umbraco.Core.Scoping; using Umbraco.Tests.TestHelpers; @@ -307,7 +305,7 @@ namespace Umbraco.Tests.Persistence.Repositories private DocumentRepository CreateRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository) { var accessor = (IScopeAccessor) provider; - var templateRepository = new TemplateRepository(accessor, CacheHelper, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepository = new TemplateRepository(accessor, CacheHelper, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, CacheHelper, Logger); contentTypeRepository = new ContentTypeRepository(accessor, CacheHelper, Logger, templateRepository); var languageRepository = new LanguageRepository(accessor, CacheHelper, Logger); diff --git a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs index 78eb736007..03295ea599 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TagRepositoryTest.cs @@ -953,7 +953,7 @@ namespace Umbraco.Tests.Persistence.Repositories private DocumentRepository CreateContentRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository) { var accessor = (IScopeAccessor) provider; - var templateRepository = new TemplateRepository(accessor, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepository = new TemplateRepository(accessor, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, CacheHelper.Disabled, Logger); contentTypeRepository = new ContentTypeRepository(accessor, CacheHelper.Disabled, Logger, templateRepository); var languageRepository = new LanguageRepository(accessor, CacheHelper.Disabled, Logger); diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index f4bed68315..7d4b413a11 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -25,11 +25,9 @@ namespace Umbraco.Tests.Persistence.Repositories { private IFileSystems _fileSystems; - private ITemplateRepository CreateRepository(IScopeProvider provider, ITemplatesSection templatesSection = null) + private ITemplateRepository CreateRepository(IScopeProvider provider) { - return new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, - templatesSection ?? Mock.Of(t => t.DefaultRenderingEngine == RenderingEngine.Mvc), - _fileSystems); + return new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, _fileSystems); } public override void SetUp() @@ -37,8 +35,6 @@ namespace Umbraco.Tests.Persistence.Repositories base.SetUp(); _fileSystems = Mock.Of(); - var masterPageFileSystem = new PhysicalFileSystem(SystemDirectories.Masterpages); - Mock.Get(_fileSystems).Setup(x => x.MasterPagesFileSystem).Returns(masterPageFileSystem); var viewsFileSystem = new PhysicalFileSystem(SystemDirectories.MvcViews); Mock.Get(_fileSystems).Setup(x => x.MvcViewsFileSystem).Returns(viewsFileSystem); } @@ -56,77 +52,6 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [Test] - public void Can_Perform_Add_MasterPage_Detect_Content() - { - // Arrange - using (ScopeProvider.CreateScope()) - { - var repository = CreateRepository(ScopeProvider); - - // Act - var template = new Template("test", "test") - { - Content = @"<%@ Master Language=""C#"" %>" - }; - repository.Save(template); - - //Assert - Assert.That(repository.Get("test"), Is.Not.Null); - Assert.That(_fileSystems.MasterPagesFileSystem.FileExists("test.master"), Is.True); - } - } - - [Test] - public void Can_Perform_Add_MasterPage_With_Default_Content() - { - // Arrange - using (ScopeProvider.CreateScope()) - { - var repository = CreateRepository(ScopeProvider, Mock.Of(x => x.DefaultRenderingEngine == RenderingEngine.WebForms)); - - // Act - var template = new Template("test", "test"); - repository.Save(template); - - //Assert - Assert.That(repository.Get("test"), Is.Not.Null); - Assert.That(_fileSystems.MasterPagesFileSystem.FileExists("test.master"), Is.True); - Assert.AreEqual(@"<%@ Master Language=""C#"" MasterPageFile=""~/umbraco/masterpages/default.master"" AutoEventWireup=""true"" %> - - - - -".StripWhitespace(), template.Content.StripWhitespace()); - } - } - - [Test] - public void Can_Perform_Add_MasterPage_With_Default_Content_With_Parent() - { - // Arrange - using (ScopeProvider.CreateScope()) - { - var repository = CreateRepository(ScopeProvider, Mock.Of(x => x.DefaultRenderingEngine == RenderingEngine.WebForms)); - - //NOTE: This has to be persisted first - var template = new Template("test", "test"); - repository.Save(template); - - // Act - var template2 = new Template("test2", "test2"); - template2.SetMasterTemplate(template); - repository.Save(template2); - - //Assert - Assert.That(repository.Get("test2"), Is.Not.Null); - Assert.That(_fileSystems.MasterPagesFileSystem.FileExists("test2.master"), Is.True); - Assert.AreEqual(@"<%@ Master Language=""C#"" MasterPageFile=""~/masterpages/test.master"" AutoEventWireup=""true"" %> - -".StripWhitespace(), template2.Content.StripWhitespace()); - } - } - [Test] public void Can_Perform_Add_View() { @@ -253,32 +178,6 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [Test] - public void Can_Perform_Update_MasterPage() - { - // Arrange - using (ScopeProvider.CreateScope()) - { - var repository = CreateRepository(ScopeProvider); - - // Act - var template = new Template("test", "test") - { - Content = @"<%@ Master Language=""C#"" %>" - }; - repository.Save(template); - - template.Content = @"<%@ Master Language=""VB"" %>"; - repository.Save(template); - - var updated = repository.Get("test"); - - // Assert - Assert.That(_fileSystems.MasterPagesFileSystem.FileExists("test.master"), Is.True); - Assert.That(updated.Content, Is.EqualTo(@"<%@ Master Language=""VB"" %>")); - } - } - [Test] public void Can_Perform_Update_View() { @@ -305,31 +204,6 @@ namespace Umbraco.Tests.Persistence.Repositories } } - [Test] - public void Can_Perform_Delete_MasterPage() - { - // Arrange - using (ScopeProvider.CreateScope()) - { - var repository = CreateRepository(ScopeProvider); - - var template = new Template("test", "test") - { - Content = @"<%@ Master Language=""C#"" %>" - }; - repository.Save(template); - - // Act - var templates = repository.Get("test"); - Assert.That(_fileSystems.MasterPagesFileSystem.FileExists("test.master"), Is.True); - repository.Delete(templates); - - // Assert - Assert.IsNull(repository.Get("test")); - Assert.That(_fileSystems.MasterPagesFileSystem.FileExists("test.master"), Is.False); - } - } - [Test] public void Can_Perform_Delete_View() { @@ -651,11 +525,6 @@ namespace Umbraco.Tests.Persistence.Repositories _fileSystems = null; //Delete all files - var fsMaster = new PhysicalFileSystem(SystemDirectories.Masterpages); - var masterPages = fsMaster.GetFiles("", "*.master"); - foreach (var file in masterPages) - fsMaster.DeleteFile(file); - var fsViews = new PhysicalFileSystem(SystemDirectories.MvcViews); var views = fsViews.GetFiles("", "*.cshtml"); foreach (var file in views) diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs index 847972cc50..ba2a7de859 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs @@ -41,7 +41,7 @@ namespace Umbraco.Tests.Persistence.Repositories private DocumentRepository CreateContentRepository(IScopeProvider provider, out IContentTypeRepository contentTypeRepository, out ITemplateRepository templateRepository) { var accessor = (IScopeAccessor) provider; - templateRepository = new TemplateRepository(accessor, CacheHelper, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + templateRepository = new TemplateRepository(accessor, CacheHelper, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, CacheHelper, Logger); contentTypeRepository = new ContentTypeRepository(accessor, CacheHelper, Logger, templateRepository); var languageRepository = new LanguageRepository(accessor, CacheHelper, Logger); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index 3af930c4c3..73f3cd1537 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -97,7 +97,7 @@ namespace Umbraco.Tests.PublishedContent { var doc = GetContent(true, 1); //change a doc type alias - var c = (TestPublishedContent) doc.Children.ElementAt(0); + var c = (TestPublishedContent)doc.Children.ElementAt(0); c.ContentType = new PublishedContentType(22, "DontMatch", PublishedItemType.Content, Enumerable.Empty(), Enumerable.Empty(), ContentVariation.Nothing); var dt = doc.ChildrenAsTable(Current.Services, "Child"); diff --git a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs index 3aefa88a50..fff88d7531 100644 --- a/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs +++ b/src/Umbraco.Tests/Services/ContentServicePerformanceTest.cs @@ -163,7 +163,7 @@ namespace Umbraco.Tests.Services var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) { - var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, tRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); @@ -196,7 +196,7 @@ namespace Umbraco.Tests.Services var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) { - var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, tRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); @@ -227,7 +227,7 @@ namespace Umbraco.Tests.Services var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) { - var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, tRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); @@ -261,7 +261,7 @@ namespace Umbraco.Tests.Services var provider = TestObjects.GetScopeProvider(Logger); using (var scope = provider.CreateScope()) { - var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var tRepository = new TemplateRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepo = new TagRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger, tRepository); var languageRepository = new LanguageRepository((IScopeAccessor) provider, CacheHelper.Disabled, Logger); diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs index 0f48a9c99a..a9e48988f4 100644 --- a/src/Umbraco.Tests/Services/ContentServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs @@ -3037,7 +3037,7 @@ namespace Umbraco.Tests.Services private DocumentRepository CreateRepository(IScopeProvider provider, out ContentTypeRepository contentTypeRepository) { var accessor = (IScopeAccessor) provider; - var templateRepository = new TemplateRepository(accessor, CacheHelper.Disabled, Logger, Mock.Of(), TestObjects.GetFileSystemsMock()); + var templateRepository = new TemplateRepository(accessor, CacheHelper.Disabled, Logger, TestObjects.GetFileSystemsMock()); var tagRepository = new TagRepository(accessor, CacheHelper.Disabled, Logger); contentTypeRepository = new ContentTypeRepository(accessor, CacheHelper.Disabled, Logger, templateRepository); var languageRepository = new LanguageRepository(accessor, CacheHelper.Disabled, Logger); diff --git a/src/Umbraco.Tests/Services/Importing/Fanoe-Package.xml b/src/Umbraco.Tests/Services/Importing/Fanoe-Package.xml index 5f6371bba1..baadf0340f 100644 --- a/src/Umbraco.Tests/Services/Importing/Fanoe-Package.xml +++ b/src/Umbraco.Tests/Services/Importing/Fanoe-Package.xml @@ -4163,7 +4163,7 @@ html { text-align: center; } -.text--center .seperator { +.text--center .separator { margin-right: auto; margin-left: auto; } @@ -4998,4 +4998,4 @@ nav > ul li.active ul li a { - \ No newline at end of file + diff --git a/src/Umbraco.Tests/Services/SectionServiceTests.cs b/src/Umbraco.Tests/Services/SectionServiceTests.cs index ca5d755220..84eb0d1cbc 100644 --- a/src/Umbraco.Tests/Services/SectionServiceTests.cs +++ b/src/Umbraco.Tests/Services/SectionServiceTests.cs @@ -1,8 +1,10 @@ using NUnit.Framework; using System.Linq; using System.Threading; +using Umbraco.Core.Composing; using Umbraco.Core.Models.Membership; using Umbraco.Tests.Testing; +using Umbraco.Web.Services; namespace Umbraco.Tests.Services { @@ -14,15 +16,7 @@ namespace Umbraco.Tests.Services [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest, WithApplication = true)] public class SectionServiceTests : TestWithSomeContentBase { - public override void CreateTestData() - { - base.CreateTestData(); - - ServiceContext.SectionService.MakeNew("Content", "content", "icon-content"); - ServiceContext.SectionService.MakeNew("Media", "media", "icon-media"); - ServiceContext.SectionService.MakeNew("Settings", "settings", "icon-settings"); - ServiceContext.SectionService.MakeNew("Developer", "developer", "icon-developer"); - } + private ISectionService SectionService => Factory.GetInstance(); [Test] public void SectionService_Can_Get_Allowed_Sections_For_User() @@ -31,7 +25,7 @@ namespace Umbraco.Tests.Services var user = CreateTestUser(); // Act - var result = ServiceContext.SectionService.GetAllowedSections(user.Id).ToList(); + var result = SectionService.GetAllowedSections(user.Id).ToList(); // Assert Assert.AreEqual(3, result.Count); @@ -63,7 +57,7 @@ namespace Umbraco.Tests.Services Name = "Group B" }; userGroupB.AddAllowedSection("settings"); - userGroupB.AddAllowedSection("developer"); + userGroupB.AddAllowedSection("member"); ServiceContext.UserService.Save(userGroupB, new[] { user.Id }, false); return ServiceContext.UserService.GetUserById(user.Id); diff --git a/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs b/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs deleted file mode 100644 index a8344893c0..0000000000 --- a/src/Umbraco.Tests/Templates/MasterPageHelperTests.cs +++ /dev/null @@ -1,21 +0,0 @@ -using NUnit.Framework; -using Umbraco.Core.IO; - -namespace Umbraco.Tests.Templates -{ - [TestFixture] - public class MasterPageHelperTests - { - - [TestCase(@"<%@ master language=""C#"" masterpagefile=""~/masterpages/umbMaster.master"" autoeventwireup=""true"" %>")] - [TestCase(@"<%@ Master language=""C#"" masterpagefile=""~/masterpages/umbMaster.master"" autoeventwireup=""true"" %>")] - [TestCase(@"<%@Master language=""C#"" masterpagefile=""~/masterpages/umbMaster.master"" autoeventwireup=""true"" %>")] - [TestCase(@"<%@ Master language=""C#"" masterpagefile=""~/masterpages/umbMaster.master"" autoeventwireup=""true"" %>")] - [TestCase(@"<%@master language=""C#"" masterpagefile=""~/masterpages/umbMaster.master"" autoeventwireup=""true"" %>")] - public void IsMasterPageSyntax(string design) - { - Assert.IsTrue(MasterPageHelper.IsMasterPageSyntax(design)); - } - - } -} diff --git a/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs b/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs deleted file mode 100644 index 795d79ced1..0000000000 --- a/src/Umbraco.Tests/Templates/TemplateRepositoryTests.cs +++ /dev/null @@ -1,121 +0,0 @@ -using Moq; -using NUnit.Framework; -using Umbraco.Core; -using Umbraco.Core.Cache; -using Umbraco.Core.Configuration.UmbracoSettings; -using Umbraco.Core.IO; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Repositories.Implement; -using Umbraco.Core.Scoping; -using Umbraco.Tests.TestHelpers; - -namespace Umbraco.Tests.Templates -{ - [TestFixture] - public class TemplateRepositoryTests - { - private readonly Mock _cacheMock = new Mock(); - private readonly Mock _templateConfigMock = new Mock(); - private readonly IFileSystems _fileSystems = Mock.Of(); - private TemplateRepository _templateRepository; - - private readonly TestObjects _testObjects = new TestObjects(null); - - [SetUp] - public void Setup() - { - var logger = Mock.Of(); - - var accessorMock = new Mock(); - var scopeMock = new Mock(); - var database = _testObjects.GetUmbracoSqlCeDatabase(logger); - scopeMock.Setup(x => x.Database).Returns(database); - accessorMock.Setup(x => x.AmbientScope).Returns(scopeMock.Object); - - var mvcFs = Mock.Of(); - var masterFs = Mock.Of(); - Mock.Get(_fileSystems).Setup(x => x.MvcViewsFileSystem).Returns(mvcFs); - Mock.Get(_fileSystems).Setup(x => x.MasterPagesFileSystem).Returns(masterFs); - - _templateRepository = new TemplateRepository(accessorMock.Object, _cacheMock.Object, logger, _templateConfigMock.Object, _fileSystems); - } - - [Test] - public void DetermineTemplateRenderingEngine_Returns_MVC_When_ViewFile_Exists_And_Content_Has_Webform_Markup() - { - // Project in MVC mode - _templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.Mvc); - - // Template has masterpage content - var templateMock = new Mock(); - templateMock.Setup(x => x.Alias).Returns("Something"); - templateMock.Setup(x => x.Content).Returns(""); - - // but MVC View already exists - Mock.Get(_fileSystems.MvcViewsFileSystem) - .Setup(x => x.FileExists(It.IsAny())).Returns(true); - - var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object); - Assert.AreEqual(RenderingEngine.Mvc, res); - } - - [Test] - public void DetermineTemplateRenderingEngine_Returns_WebForms_When_ViewFile_Doesnt_Exist_And_Content_Has_Webform_Markup() - { - // Project in MVC mode - _templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.Mvc); - - // Template has masterpage content - var templateMock = new Mock(); - templateMock.Setup(x => x.Alias).Returns("Something"); - templateMock.Setup(x => x.Content).Returns(""); - - // MVC View doesn't exist - Mock.Get(_fileSystems.MvcViewsFileSystem) - .Setup(x => x.FileExists(It.IsAny())).Returns(false); - - var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object); - Assert.AreEqual(RenderingEngine.WebForms, res); - } - - [Test] - public void DetermineTemplateRenderingEngine_Returns_WebForms_When_MasterPage_Exists_And_In_Mvc_Mode() - { - // Project in MVC mode - _templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.Mvc); - - var templateMock = new Mock(); - templateMock.Setup(x => x.Alias).Returns("Something"); - - // but masterpage already exists - Mock.Get(_fileSystems.MvcViewsFileSystem) - .Setup(x => x.FileExists(It.IsAny())).Returns(false); - Mock.Get(_fileSystems.MasterPagesFileSystem) - .Setup(x => x.FileExists(It.IsAny())).Returns(true); - - var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object); - Assert.AreEqual(RenderingEngine.WebForms, res); - } - - [Test] - public void DetermineTemplateRenderingEngine_Returns_Mvc_When_ViewPage_Exists_And_In_Webforms_Mode() - { - // Project in WebForms mode - _templateConfigMock.Setup(x => x.DefaultRenderingEngine).Returns(RenderingEngine.WebForms); - - var templateMock = new Mock(); - templateMock.Setup(x => x.Alias).Returns("Something"); - - // but MVC View already exists - Mock.Get(_fileSystems.MvcViewsFileSystem) - .Setup(x => x.FileExists(It.IsAny())).Returns(true); - Mock.Get(_fileSystems.MasterPagesFileSystem) - .Setup(x => x.FileExists(It.IsAny())).Returns(false); - - var res = _templateRepository.DetermineTemplateRenderingEngine(templateMock.Object); - Assert.AreEqual(RenderingEngine.Mvc, res); - } - - } -} diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs index 9e2a2156ee..31ee34843d 100644 --- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs +++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestControllerActivatorBase.cs @@ -60,8 +60,7 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting memberTypeService: mockedMemberTypeService, dataTypeService: mockedDataTypeService, contentTypeService: mockedContentTypeService, - localizedTextService:Mock.Of(), - sectionService:Mock.Of()); + localizedTextService:Mock.Of()); var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); diff --git a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs index ea40ed9c84..cfd935cd82 100644 --- a/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs +++ b/src/Umbraco.Tests/TestHelpers/SettingsForTests.cs @@ -38,7 +38,6 @@ namespace Umbraco.Tests.TestHelpers var content = new Mock(); var security = new Mock(); var requestHandler = new Mock(); - var templates = new Mock(); var logging = new Mock(); var tasks = new Mock(); var providers = new Mock(); @@ -47,7 +46,6 @@ namespace Umbraco.Tests.TestHelpers settings.Setup(x => x.Content).Returns(content.Object); settings.Setup(x => x.Security).Returns(security.Object); settings.Setup(x => x.RequestHandler).Returns(requestHandler.Object); - settings.Setup(x => x.Templates).Returns(templates.Object); settings.Setup(x => x.Logging).Returns(logging.Object); settings.Setup(x => x.ScheduledTasks).Returns(tasks.Object); settings.Setup(x => x.Providers).Returns(providers.Object); @@ -61,7 +59,6 @@ namespace Umbraco.Tests.TestHelpers settings.Setup(x => x.RequestHandler.UseDomainPrefixes).Returns(false); settings.Setup(x => x.RequestHandler.CharCollection).Returns(RequestHandlerElement.GetDefaultCharReplacements()); settings.Setup(x => x.WebRouting.UrlProviderMode).Returns("AutoLegacy"); - settings.Setup(x => x.Templates.DefaultRenderingEngine).Returns(RenderingEngine.Mvc); settings.Setup(x => x.Providers.DefaultBackOfficeUserProvider).Returns("UsersMembershipProvider"); return settings.Object; diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 1fe814e4c6..b6f597bf46 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -55,12 +55,12 @@ namespace Umbraco.Tests.TestHelpers public static void InitializeContentDirectories() { - CreateDirectories(new[] { SystemDirectories.Masterpages, SystemDirectories.MvcViews, SystemDirectories.Media, SystemDirectories.AppPlugins }); + CreateDirectories(new[] { SystemDirectories.MvcViews, SystemDirectories.Media, SystemDirectories.AppPlugins }); } public static void CleanContentDirectories() { - CleanDirectories(new[] { SystemDirectories.Masterpages, SystemDirectories.MvcViews, SystemDirectories.Media }); + CleanDirectories(new[] { SystemDirectories.MvcViews, SystemDirectories.Media }); } public static void CreateDirectories(string[] directories) @@ -77,7 +77,6 @@ namespace Umbraco.Tests.TestHelpers { var preserves = new Dictionary { - { SystemDirectories.Masterpages, new[] {"dummy.txt"} }, { SystemDirectories.MvcViews, new[] {"dummy.txt"} } }; foreach (var directory in directories) diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs index 8c230f98d0..c56eae9cd8 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects-Mocks.cs @@ -73,8 +73,6 @@ namespace Umbraco.Tests.TestHelpers MockService(container), MockService(container), MockService(container), - MockService(container), - MockService(container), MockService(container), MockService(container), MockService(container), @@ -145,8 +143,7 @@ namespace Umbraco.Tests.TestHelpers public IFileSystems GetFileSystemsMock() { var fileSystems = Mock.Of(); - - MockFs(fileSystems, x => x.MasterPagesFileSystem); + MockFs(fileSystems, x => x.MacroPartialsFileSystem); MockFs(fileSystems, x => x.MvcViewsFileSystem); MockFs(fileSystems, x => x.PartialViewsFileSystem); diff --git a/src/Umbraco.Tests/TestHelpers/TestObjects.cs b/src/Umbraco.Tests/TestHelpers/TestObjects.cs index 14ffeb743f..f7f0d26c0e 100644 --- a/src/Umbraco.Tests/TestHelpers/TestObjects.cs +++ b/src/Umbraco.Tests/TestHelpers/TestObjects.cs @@ -188,9 +188,7 @@ namespace Umbraco.Tests.TestHelpers new DirectoryInfo(IOHelper.GetRootDirectorySafe()))); }); var relationService = GetLazyService(factory, c => new RelationService(scopeProvider, logger, eventMessagesFactory, entityService.Value, GetRepo(c), GetRepo(c))); - var treeService = GetLazyService(factory, c => new ApplicationTreeService(logger, cache, typeLoader)); - var tagService = GetLazyService(factory, c => new TagService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); - var sectionService = GetLazyService(factory, c => new SectionService(userService.Value, treeService.Value, scopeProvider, cache)); + var tagService = GetLazyService(factory, c => new TagService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); var redirectUrlService = GetLazyService(factory, c => new RedirectUrlService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); var consentService = GetLazyService(factory, c => new ConsentService(scopeProvider, logger, eventMessagesFactory, GetRepo(c))); @@ -213,8 +211,6 @@ namespace Umbraco.Tests.TestHelpers serverRegistrationService, entityService, relationService, - treeService, - sectionService, macroService, memberTypeService, memberGroupService, diff --git a/src/Umbraco.Tests/Testing/Objects/Accessors/TestVariationContextAccessor.cs b/src/Umbraco.Tests/Testing/Objects/Accessors/TestVariationContextAccessor.cs index 3c7377f2cc..134b709447 100644 --- a/src/Umbraco.Tests/Testing/Objects/Accessors/TestVariationContextAccessor.cs +++ b/src/Umbraco.Tests/Testing/Objects/Accessors/TestVariationContextAccessor.cs @@ -8,10 +8,6 @@ namespace Umbraco.Tests.Testing.Objects.Accessors public class TestVariationContextAccessor : IVariationContextAccessor { /// - public VariationContext VariationContext - { - get; - set; - } + public VariationContext VariationContext { get; set; } } } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index a79531af74..f760903d41 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -40,6 +40,7 @@ using Umbraco.Web.Composing.Composers; using Umbraco.Web.ContentApps; using Current = Umbraco.Core.Composing.Current; using Umbraco.Web.Routing; +using Umbraco.Web.Trees; namespace Umbraco.Tests.Testing { @@ -216,6 +217,16 @@ namespace Umbraco.Tests.Testing Composition.WithCollectionBuilder(); Composition.RegisterUnique(); Composition.RegisterUnique(); + + // register back office sections in the order we want them rendered + Composition.WithCollectionBuilder().Append() + .Append() + .Append() + .Append() + .Append() + .Append() + .Append(); + Composition.RegisterUnique(); } protected virtual void ComposeWtf() @@ -304,7 +315,6 @@ namespace Umbraco.Tests.Testing // register basic stuff that might need to be there for some container resolvers to work Composition.RegisterUnique(factory => factory.GetInstance().Content); - Composition.RegisterUnique(factory => factory.GetInstance().Templates); Composition.RegisterUnique(factory => factory.GetInstance().WebRouting); Composition.RegisterUnique(factory => ExamineManager.Instance); @@ -342,7 +352,7 @@ namespace Umbraco.Tests.Testing Composition.ComposeServices(); // composition root is doing weird things, fix - Composition.RegisterUnique(); + Composition.RegisterUnique(); Composition.RegisterUnique(); // somehow property editor ends up wanting this diff --git a/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs b/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs deleted file mode 100644 index 951246c535..0000000000 --- a/src/Umbraco.Tests/TreesAndSections/ApplicationTreeTest.cs +++ /dev/null @@ -1,397 +0,0 @@ -using System.IO; -using NUnit.Framework; -using Umbraco.Core.Services; -using Umbraco.Tests.TestHelpers; -using System; -using System.Linq; -using System.Threading; -using Umbraco.Tests.Testing; -using Umbraco.Web.Services; -using Current = Umbraco.Web.Composing.Current; - -namespace Umbraco.Tests.TreesAndSections -{ - - - /// - ///This is a test class for ApplicationTreeTest and is intended - ///to contain all ApplicationTreeTest Unit Tests - /// - [TestFixture] - [Apartment(ApartmentState.STA)] - [UmbracoTest(Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class ApplicationTreeTest : TestWithDatabaseBase - { - public override void SetUp() - { - base.SetUp(); - - var treesConfig = TestHelper.MapPathForTest("~/TEMP/TreesAndSections/trees.config"); - var appConfig = TestHelper.MapPathForTest("~/TEMP/TreesAndSections/applications.config"); - Directory.CreateDirectory(TestHelper.MapPathForTest("~/TEMP/TreesAndSections")); - using (var writer = File.CreateText(treesConfig)) - { - writer.Write(ResourceFiles.trees); - } - using (var writer = File.CreateText(appConfig)) - { - writer.Write(ResourceFiles.applications); - } - - ApplicationTreeService.TreeConfigFilePath = treesConfig; - SectionService.AppConfigFilePath = appConfig; - } - - public override void TearDown() - { - base.TearDown(); - - if (Directory.Exists(TestHelper.MapPathForTest("~/TEMP/TreesAndSections"))) - { - Directory.Delete(TestHelper.MapPathForTest("~/TEMP/TreesAndSections"), true); - } - ApplicationTreeService.TreeConfigFilePath = null; - SectionService.AppConfigFilePath = null; - } - - /// - /// Creates a new app tree linked to an application, then delete the application and make sure the tree is gone as well - /// - [Test()] - public void ApplicationTree_Make_New_Then_Delete_App() - { - //create new app - var appName = Guid.NewGuid().ToString("N"); - var treeName = Guid.NewGuid().ToString("N"); - Current.Services.SectionService.MakeNew(appName, appName, "icon.jpg"); - - //check if it exists - var app = Current.Services.SectionService.GetByAlias(appName); - Assert.IsNotNull(app); - - //create the new app tree assigned to the new app - Current.Services.ApplicationTreeService.MakeNew(false, 0, app.Alias, treeName, treeName, "icon.jpg", "icon.jpg", "Umbraco.Web.Trees.ContentTreeController, Umbraco.Web"); - var tree = Current.Services.ApplicationTreeService.GetByAlias(treeName); - Assert.IsNotNull(tree); - - //now delete the app - Current.Services.SectionService.DeleteSection(app); - - //check that the tree is gone - Assert.AreEqual(0, Current.Services.ApplicationTreeService.GetApplicationTrees(treeName).Count()); - } - - - #region Tests to write - ///// - /////A test for ApplicationTree Constructor - ///// - //[TestMethod()] - //public void ApplicationTreeConstructorTest() - //{ - // bool silent = false; // TODO: Initialize to an appropriate value - // bool initialize = false; // TODO: Initialize to an appropriate value - // byte sortOrder = 0; // TODO: Initialize to an appropriate value - // string applicationAlias = string.Empty; // TODO: Initialize to an appropriate value - // string alias = string.Empty; // TODO: Initialize to an appropriate value - // string title = string.Empty; // TODO: Initialize to an appropriate value - // string iconClosed = string.Empty; // TODO: Initialize to an appropriate value - // string iconOpened = string.Empty; // TODO: Initialize to an appropriate value - // string assemblyName = string.Empty; // TODO: Initialize to an appropriate value - // string type = string.Empty; // TODO: Initialize to an appropriate value - // string action = string.Empty; // TODO: Initialize to an appropriate value - // ApplicationTree target = new ApplicationTree(silent, initialize, sortOrder, applicationAlias, alias, title, iconClosed, iconOpened, assemblyName, type, action); - // Assert.Inconclusive("TODO: Implement code to verify target"); - //} - - ///// - /////A test for ApplicationTree Constructor - ///// - //[TestMethod()] - //public void ApplicationTreeConstructorTest1() - //{ - // ApplicationTree target = new ApplicationTree(); - // Assert.Inconclusive("TODO: Implement code to verify target"); - //} - - ///// - /////A test for Delete - ///// - //[TestMethod()] - //public void DeleteTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // target.Delete(); - // Assert.Inconclusive("A method that does not return a value cannot be verified."); - //} - - - ///// - /////A test for Save - ///// - //[TestMethod()] - //public void SaveTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // target.Save(); - // Assert.Inconclusive("A method that does not return a value cannot be verified."); - //} - - ///// - /////A test for getAll - ///// - //[TestMethod()] - //public void getAllTest() - //{ - // ApplicationTree[] expected = null; // TODO: Initialize to an appropriate value - // ApplicationTree[] actual; - // actual = ApplicationTree.getAll(); - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for getApplicationTree - ///// - //[TestMethod()] - //public void getApplicationTreeTest() - //{ - // string applicationAlias = string.Empty; // TODO: Initialize to an appropriate value - // ApplicationTree[] expected = null; // TODO: Initialize to an appropriate value - // ApplicationTree[] actual; - // actual = ApplicationTree.getApplicationTree(applicationAlias); - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for getApplicationTree - ///// - //[TestMethod()] - //public void getApplicationTreeTest1() - //{ - // string applicationAlias = string.Empty; // TODO: Initialize to an appropriate value - // bool onlyInitializedApplications = false; // TODO: Initialize to an appropriate value - // ApplicationTree[] expected = null; // TODO: Initialize to an appropriate value - // ApplicationTree[] actual; - // actual = ApplicationTree.getApplicationTree(applicationAlias, onlyInitializedApplications); - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for getByAlias - ///// - //[TestMethod()] - //public void getByAliasTest() - //{ - // string treeAlias = string.Empty; // TODO: Initialize to an appropriate value - // ApplicationTree expected = null; // TODO: Initialize to an appropriate value - // ApplicationTree actual; - // actual = ApplicationTree.getByAlias(treeAlias); - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for Action - ///// - //[TestMethod()] - //public void ActionTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.Action = expected; - // actual = target.Action; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for Alias - ///// - //[TestMethod()] - //public void AliasTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string actual; - // actual = target.Alias; - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for ApplicationAlias - ///// - //[TestMethod()] - //public void ApplicationAliasTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string actual; - // actual = target.ApplicationAlias; - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for AssemblyName - ///// - //[TestMethod()] - //public void AssemblyNameTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.AssemblyName = expected; - // actual = target.AssemblyName; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for IconClosed - ///// - //[TestMethod()] - //public void IconClosedTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.IconClosed = expected; - // actual = target.IconClosed; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for IconOpened - ///// - //[TestMethod()] - //public void IconOpenedTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.IconOpened = expected; - // actual = target.IconOpened; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for Initialize - ///// - //[TestMethod()] - //public void InitializeTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // bool expected = false; // TODO: Initialize to an appropriate value - // bool actual; - // target.Initialize = expected; - // actual = target.Initialize; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for Silent - ///// - //[TestMethod()] - //public void SilentTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // bool expected = false; // TODO: Initialize to an appropriate value - // bool actual; - // target.Silent = expected; - // actual = target.Silent; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for SortOrder - ///// - //[TestMethod()] - //public void SortOrderTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // byte expected = 0; // TODO: Initialize to an appropriate value - // byte actual; - // target.SortOrder = expected; - // actual = target.SortOrder; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for SqlHelper - ///// - //[TestMethod()] - //public void SqlHelperTest() - //{ - // ISqlHelper actual; - // actual = ApplicationTree.SqlHelper; - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for Title - ///// - //[TestMethod()] - //public void TitleTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.Title = expected; - // actual = target.Title; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for Type - ///// - //[TestMethod()] - //public void TypeTest() - //{ - // ApplicationTree target = new ApplicationTree(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.Type = expected; - // actual = target.Type; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - #endregion - - #region Additional test attributes - // - //You can use the following additional attributes as you write your tests: - // - //Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - //public static void MyClassInitialize(TestContext testContext) - //{ - //} - // - //Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - //public static void MyClassCleanup() - //{ - //} - // - //Use TestInitialize to run code before running each test - //[TestInitialize()] - //public void MyTestInitialize() - //{ - //} - // - //Use TestCleanup to run code after each test has run - //[TestCleanup()] - //public void MyTestCleanup() - //{ - //} - // - #endregion - } -} diff --git a/src/Umbraco.Tests/TreesAndSections/ResourceFiles.Designer.cs b/src/Umbraco.Tests/TreesAndSections/ResourceFiles.Designer.cs deleted file mode 100644 index 02bc84649e..0000000000 --- a/src/Umbraco.Tests/TreesAndSections/ResourceFiles.Designer.cs +++ /dev/null @@ -1,91 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Tests.TreesAndSections { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class ResourceFiles { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal ResourceFiles() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Umbraco.Tests.TreesAndSections.ResourceFiles", typeof(ResourceFiles).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - - /// - /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> - ///<applications> - /// <add alias="content" name="content" icon="file" sortOrder="0" /> - /// <add alias="0b486ac9c0f1456996192c6ed1f03e57" name="0b486ac9c0f1456996192c6ed1f03e57" icon="icon.jpg" sortOrder="1" /> - /// <add alias="1ffbc301744c4e75ae3054d741954c7b" name="1ffbc301744c4e75ae3054d741954c7b" icon="icon.jpg" sortOrder="2" /> - /// <add alias="1838c3e1591f4008bbafe59a06a00a31" name="1838c3e1591f4008bbafe59a06a00a31" icon="icon.jpg" sortOrder="3" /> - /// <add alias="e5badae2 [rest of string was truncated]";. - /// - internal static string applications { - get { - return ResourceManager.GetString("applications", resourceCulture); - } - } - - /// - /// Looks up a localized string similar to <?xml version="1.0" encoding="utf-8"?> - ///<trees> - /// <add initialize="false" sortOrder="0" alias="1838c3e1591f4008bbafe59a06a00a31" application="1838c3e1591f4008bbafe59a06a00a31" title="1838c3e1591f4008bbafe59a06a00a31" iconClosed="icon.jpg" iconOpen="icon.jpg" type="nulltype" /> - /// <add initialize="false" sortOrder="0" alias="e5badae2fc5e4cd7acb3700320e33b8b" application="e5badae2fc5e4cd7acb3700320e33b8b" title="e5badae2fc5e4cd7acb3700320e33b8b" iconClosed="icon.jpg" iconOpen="icon.jpg" type="nulltype" /> - /// [rest of string was truncated]";. - /// - internal static string trees { - get { - return ResourceManager.GetString("trees", resourceCulture); - } - } - } -} diff --git a/src/Umbraco.Tests/TreesAndSections/ResourceFiles.resx b/src/Umbraco.Tests/TreesAndSections/ResourceFiles.resx deleted file mode 100644 index fac58dc842..0000000000 --- a/src/Umbraco.Tests/TreesAndSections/ResourceFiles.resx +++ /dev/null @@ -1,127 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - - applications.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - - trees.config;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8 - - \ No newline at end of file diff --git a/src/Umbraco.Tests/TreesAndSections/SectionTests.cs b/src/Umbraco.Tests/TreesAndSections/SectionTests.cs deleted file mode 100644 index 1f4a01fd3d..0000000000 --- a/src/Umbraco.Tests/TreesAndSections/SectionTests.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System.IO; -using NUnit.Framework; -using Umbraco.Core.Services; -using Umbraco.Tests.TestHelpers; -using System; -using Umbraco.Core.Composing; -using Umbraco.Tests.Testing; -using Umbraco.Web.Services; - -namespace Umbraco.Tests.TreesAndSections -{ - /// - ///This is a test class for ApplicationTest and is intended - ///to contain all ApplicationTest Unit Tests - /// - [TestFixture] - [UmbracoTest(AutoMapper = true, Database = UmbracoTestOptions.Database.NewSchemaPerTest)] - public class SectionTests : TestWithDatabaseBase - { - protected override void Compose() - { - base.Compose(); - Composition.RegisterUnique(); - } - - public override void SetUp() - { - base.SetUp(); - - var treesConfig = TestHelper.MapPathForTest("~/TEMP/TreesAndSections/trees.config"); - var appConfig = TestHelper.MapPathForTest("~/TEMP/TreesAndSections/applications.config"); - Directory.CreateDirectory(TestHelper.MapPathForTest("~/TEMP/TreesAndSections")); - using (var writer = File.CreateText(treesConfig)) - { - writer.Write(ResourceFiles.trees); - } - using (var writer = File.CreateText(appConfig)) - { - writer.Write(ResourceFiles.applications); - } - - ApplicationTreeService.TreeConfigFilePath = treesConfig; - SectionService.AppConfigFilePath = appConfig; - } - - public override void TearDown() - { - base.TearDown(); - - if (Directory.Exists(TestHelper.MapPathForTest("~/TEMP/TreesAndSections"))) - { - Directory.Delete(TestHelper.MapPathForTest("~/TEMP/TreesAndSections"), true); - } - ApplicationTreeService.TreeConfigFilePath = null; - SectionService.AppConfigFilePath = null; - } - - /// - /// Create a new application and delete it - /// - [Test()] - public void Application_Make_New() - { - var name = Guid.NewGuid().ToString("N"); - ServiceContext.SectionService.MakeNew(name, name, "icon.jpg"); - - //check if it exists - var app = ServiceContext.SectionService.GetByAlias(name); - Assert.IsNotNull(app); - - //now remove it - ServiceContext.SectionService.DeleteSection(app); - Assert.IsNull(ServiceContext.SectionService.GetByAlias(name)); - } - - #region Tests to write - - - ///// - /////A test for Application Constructor - ///// - //[TestMethod()] - //public void ApplicationConstructorTest() - //{ - // string name = string.Empty; // TODO: Initialize to an appropriate value - // string alias = string.Empty; // TODO: Initialize to an appropriate value - // string icon = string.Empty; // TODO: Initialize to an appropriate value - // Application target = new Application(name, alias, icon); - // Assert.Inconclusive("TODO: Implement code to verify target"); - //} - - ///// - /////A test for Application Constructor - ///// - //[TestMethod()] - //public void ApplicationConstructorTest1() - //{ - // Application target = new Application(); - // Assert.Inconclusive("TODO: Implement code to verify target"); - //} - - ///// - /////A test for Delete - ///// - //[TestMethod()] - //public void DeleteTest() - //{ - // Application target = new Application(); // TODO: Initialize to an appropriate value - // target.Delete(); - // Assert.Inconclusive("A method that does not return a value cannot be verified."); - //} - - - - ///// - /////A test for MakeNew - ///// - //[TestMethod()] - //public void MakeNewTest1() - //{ - // string name = string.Empty; // TODO: Initialize to an appropriate value - // string alias = string.Empty; // TODO: Initialize to an appropriate value - // string icon = string.Empty; // TODO: Initialize to an appropriate value - // Application.MakeNew(name, alias, icon); - // Assert.Inconclusive("A method that does not return a value cannot be verified."); - //} - - ///// - /////A test for RegisterIApplications - ///// - //[TestMethod()] - //public void RegisterIApplicationsTest() - //{ - // Application.RegisterIApplications(); - // Assert.Inconclusive("A method that does not return a value cannot be verified."); - //} - - ///// - /////A test for getAll - ///// - //[TestMethod()] - //public void getAllTest() - //{ - // List expected = null; // TODO: Initialize to an appropriate value - // List actual; - // actual = Application.getAll(); - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for getByAlias - ///// - //[TestMethod()] - //public void getByAliasTest() - //{ - // string appAlias = string.Empty; // TODO: Initialize to an appropriate value - // Application expected = null; // TODO: Initialize to an appropriate value - // Application actual; - // actual = Application.getByAlias(appAlias); - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for SqlHelper - ///// - //[TestMethod()] - //public void SqlHelperTest() - //{ - // ISqlHelper actual; - // actual = Application.SqlHelper; - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for alias - ///// - //[TestMethod()] - //public void aliasTest() - //{ - // Application target = new Application(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.alias = expected; - // actual = target.alias; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for icon - ///// - //[TestMethod()] - //public void iconTest() - //{ - // Application target = new Application(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.icon = expected; - // actual = target.icon; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - - ///// - /////A test for name - ///// - //[TestMethod()] - //public void nameTest() - //{ - // Application target = new Application(); // TODO: Initialize to an appropriate value - // string expected = string.Empty; // TODO: Initialize to an appropriate value - // string actual; - // target.name = expected; - // actual = target.name; - // Assert.AreEqual(expected, actual); - // Assert.Inconclusive("Verify the correctness of this test method."); - //} - #endregion - - #region Additional test attributes - // - //You can use the following additional attributes as you write your tests: - // - //Use ClassInitialize to run code before running the first test in the class - //[ClassInitialize()] - //public static void MyClassInitialize(TestContext testContext) - //{ - //} - // - //Use ClassCleanup to run code after all tests in a class have run - //[ClassCleanup()] - //public static void MyClassCleanup() - //{ - //} - // - //Use TestInitialize to run code before running each test - //[TestInitialize()] - //public void MyTestInitialize() - //{ - //} - // - //Use TestCleanup to run code after each test has run - //[TestCleanup()] - //public void MyTestCleanup() - //{ - //} - // - #endregion - } -} diff --git a/src/Umbraco.Tests/TreesAndSections/applications.config b/src/Umbraco.Tests/TreesAndSections/applications.config deleted file mode 100644 index aadd1c5407..0000000000 --- a/src/Umbraco.Tests/TreesAndSections/applications.config +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Tests/TreesAndSections/trees.config b/src/Umbraco.Tests/TreesAndSections/trees.config deleted file mode 100644 index d21fea28a9..0000000000 --- a/src/Umbraco.Tests/TreesAndSections/trees.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index e49ba250fa..de1fc18249 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -305,8 +305,6 @@ - - @@ -354,7 +352,6 @@ - @@ -423,13 +420,6 @@ - - True - True - ResourceFiles.resx - - - @@ -453,7 +443,6 @@ - @@ -525,8 +514,6 @@ Designer Always - - Designer @@ -561,10 +548,6 @@ ImportResources.Designer.cs Designer - - ResXFileCodeGenerator - ResourceFiles.Designer.cs - ResXFileCodeGenerator TestFiles.Designer.cs diff --git a/src/Umbraco.Web.UI.Client/gulp/config.js b/src/Umbraco.Web.UI.Client/gulp/config.js new file mode 100755 index 0000000000..c27a2c5f53 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/config.js @@ -0,0 +1,52 @@ +'use strict'; + +module.exports = { + sources: { + + //less files used by backoffice and preview + //processed in the less task + less: { + installer: { files: ["./src/less/installer.less"], out: "installer.css" }, + nonodes: { files: ["./src/less/pages/nonodes.less"], out: "nonodes.style.min.css"}, + preview: { files: ["./src/less/canvas-designer.less"], out: "canvasdesigner.css" }, + umbraco: { files: ["./src/less/belle.less"], out: "umbraco.css" } + }, + + //js files for backoffie + //processed in the js task + js: { + preview: { files: ["./src/preview/**/*.js"], out: "umbraco.preview.js" }, + installer: { files: ["./src/installer/**/*.js"], out: "umbraco.installer.js" }, + controllers: { files: ["./src/{views,controllers}/**/*.controller.js"], out: "umbraco.controllers.js" }, + directives: { files: ["./src/common/directives/**/*.js"], out: "umbraco.directives.js" }, + filters: { files: ["./src/common/filters/**/*.js"], out: "umbraco.filters.js" }, + resources: { files: ["./src/common/resources/**/*.js"], out: "umbraco.resources.js" }, + services: { files: ["./src/common/services/**/*.js"], out: "umbraco.services.js" }, + security: { files: ["./src/common/interceptors/**/*.js"], out: "umbraco.interceptors.js" } + }, + + //selectors for copying all views into the build + //processed in the views task + views:{ + umbraco: {files: ["./src/views/**/*.html"], folder: ""}, + installer: {files: ["./src/installer/steps/*.html"], folder: "install/"} + }, + + //globs for file-watching + globs:{ + views: "./src/views/**/*.html", + less: "./src/less/**/*.less", + js: "./src/*.js", + lib: "./lib/**/*", + assets: "./src/assets/**" + } + }, + root: "../Umbraco.Web.UI/Umbraco/", + targets: { + js: "js/", + lib: "lib/", + views: "views/", + css: "assets/css/", + assets: "assets/" + } +}; diff --git a/src/Umbraco.Web.UI.Client/gulp/index.js b/src/Umbraco.Web.UI.Client/gulp/index.js new file mode 100755 index 0000000000..9dd80598af --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/index.js @@ -0,0 +1,10 @@ +'use strict'; + +var fs = require('fs'); + +var onlyScripts = require('./util/scriptFilter'); +var tasks = fs.readdirSync('./gulp/tasks/').filter(onlyScripts); + +tasks.forEach(function(task) { + require('./tasks/' + task); +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/build.js b/src/Umbraco.Web.UI.Client/gulp/tasks/build.js new file mode 100644 index 0000000000..4e519c58e9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/build.js @@ -0,0 +1,10 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); +var runSequence = require('run-sequence'); + +// Build - build the files ready for production +gulp.task('build', function(cb) { + runSequence(["dependencies", "js", "less", "views"], cb); +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js new file mode 100644 index 0000000000..8032274ee7 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/dependencies.js @@ -0,0 +1,288 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); + +var MergeStream = require('merge-stream'); + +var imagemin = require('gulp-imagemin'); + +/************************** + * Task processes and copies all dependencies, either installed by npm or stored locally in the project + **************************/ +gulp.task('dependencies', function () { + + //as we do multiple things in this task, we merge the multiple streams + var stream = new MergeStream(); + + // Pick the dependencies we need from each package + // so we don't just ship with a lot of files that aren't needed + const nodeModules = [ + { + "name": "ace-builds", + "src": [ + "./node_modules/ace-builds/src-min-noconflict/ace.js", + "./node_modules/ace-builds/src-min-noconflict/ext-language_tools.js", + "./node_modules/ace-builds/src-min-noconflict/ext-searchbox.js", + "./node_modules/ace-builds/src-min-noconflict/ext-settings_menu.js", + "./node_modules/ace-builds/src-min-noconflict/snippets/text.js", + "./node_modules/ace-builds/src-min-noconflict/snippets/javascript.js", + "./node_modules/ace-builds/src-min-noconflict/snippets/css.js", + "./node_modules/ace-builds/src-min-noconflict/theme-chrome.js", + "./node_modules/ace-builds/src-min-noconflict/mode-razor.js", + "./node_modules/ace-builds/src-min-noconflict/mode-javascript.js", + "./node_modules/ace-builds/src-min-noconflict/mode-css.js", + "./node_modules/ace-builds/src-min-noconflict/worker-javascript.js", + "./node_modules/ace-builds/src-min-noconflict/worker-css.js" + ], + "base": "./node_modules/ace-builds" + }, + { + "name": "angular", + "src": ["./node_modules/angular/angular.js"], + "base": "./node_modules/angular" + }, + { + "name": "angular-cookies", + "src": ["./node_modules/angular-cookies/angular-cookies.js"], + "base": "./node_modules/angular-cookies" + }, + { + "name": "angular-dynamic-locale", + "src": [ + "./node_modules/angular-dynamic-locale/dist/tmhDynamicLocale.min.js", + "./node_modules/angular-dynamic-locale/dist/tmhDynamicLocale.min.js.map" + ], + "base": "./node_modules/angular-dynamic-locale/dist" + }, + { + "name": "angular-sanitize", + "src": ["./node_modules/angular-sanitize/angular-sanitize.js"], + "base": "./node_modules/angular-sanitize" + }, + { + "name": "angular-touch", + "src": ["./node_modules/angular-touch/angular-touch.js"], + "base": "./node_modules/angular-touch" + }, + { + "name": "angular-ui-sortable", + "src": ["./node_modules/angular-ui-sortable/dist/sortable.js"], + "base": "./node_modules/angular-ui-sortable/dist" + }, + { + "name": "angular-route", + "src": ["./node_modules/angular-route/angular-route.js"], + "base": "./node_modules/angular-route" + }, + { + "name": "angular-animate", + "src": ["./node_modules/angular-animate/angular-animate.js"], + "base": "./node_modules/angular-animate" + }, + { + "name": "angular-i18n", + "src": [ + "./node_modules/angular-i18n/angular-i18n.js", + "./node_modules/angular-i18n/angular-locale_*.js" + ], + "base": "./node_modules/angular-i18n" + }, + { + "name": "angular-local-storage", + "src": [ + "./node_modules/angular-local-storage/dist/angular-local-storage.min.js", + "./node_modules/angular-local-storage/dist/angular-local-storage.min.js.map" + ], + "base": "./node_modules/angular-local-storage/dist" + }, + { + "name": "angular-messages", + "src": ["./node_modules/angular-messages/angular-messages.js"], + "base": "./node_modules/angular-messages" + }, + { + "name": "angular-mocks", + "src": ["./node_modules/angular-mocks/angular-mocks.js"], + "base": "./node_modules/angular-mocks" + }, + { + "name": "animejs", + "src": ["./node_modules/animejs/anime.min.js"], + "base": "./node_modules/animejs" + }, + { + "name": "bootstrap-social", + "src": ["./node_modules/bootstrap-social/bootstrap-social.css"], + "base": "./node_modules/bootstrap-social" + }, + + { + "name": "angular-chart.js", + "src": ["./node_modules/angular-chart.js/dist/angular-chart.min.js"], + "base": "./node_modules/angular-chart.js/dist" + }, + { + "name": "chart.js", + "src": ["./node_modules/chart.js/dist/chart.min.js"], + "base": "./node_modules/chart.js/dist" + }, + { + "name": "clipboard", + "src": ["./node_modules/clipboard/dist/clipboard.min.js"], + "base": "./node_modules/clipboard/dist" + }, + { + "name": "jsdiff", + "src": ["./node_modules/diff/dist/diff.min.js"], + "base": "./node_modules/diff/dist" + }, + { + "name": "flatpickr", + "src": [ + "./node_modules/flatpickr/dist/flatpickr.js", + "./node_modules/flatpickr/dist/flatpickr.css" + ], + "base": "./node_modules/flatpickr/dist" + }, + { + "name": "font-awesome", + "src": [ + "./node_modules/font-awesome/fonts/*", + "./node_modules/font-awesome/css/font-awesome.min.css" + ], + "base": "./node_modules/font-awesome" + }, + { + "name": "jquery", + "src": [ + "./node_modules/jquery/dist/jquery.min.js", + "./node_modules/jquery/dist/jquery.min.map" + ], + "base": "./node_modules/jquery/dist" + }, + { + "name": "jquery-ui", + "src": ["./node_modules/jquery-ui-dist/jquery-ui.min.js"], + "base": "./node_modules/jquery-ui-dist" + }, + { + "name": "jquery-ui-touch-punch", + "src": ["./node_modules/jquery-ui-touch-punch/jquery.ui.touch-punch.min.js"], + "base": "./node_modules/jquery-ui-touch-punch" + }, + { + "name": "lazyload-js", + "src": ["./node_modules/lazyload-js/lazyload.min.js"], + "base": "./node_modules/lazyload-js" + }, + { + "name": "moment", + "src": ["./node_modules/moment/min/moment.min.js"], + "base": "./node_modules/moment/min" + }, + { + "name": "moment", + "src": ["./node_modules/moment/locale/*.js"], + "base": "./node_modules/moment/locale" + }, + { + "name": "ng-file-upload", + "src": ["./node_modules/ng-file-upload/dist/ng-file-upload.min.js"], + "base": "./node_modules/ng-file-upload/dist" + }, + { + "name": "nouislider", + "src": [ + "./node_modules/nouislider/distribute/nouislider.min.js", + "./node_modules/nouislider/distribute/nouislider.min.css" + ], + "base": "./node_modules/nouislider/distribute" + }, + { + "name": "signalr", + "src": ["./node_modules/signalr/jquery.signalR.js"], + "base": "./node_modules/signalr" + }, + { + "name": "spectrum", + "src": [ + "./node_modules/spectrum-colorpicker/spectrum.js", + "./node_modules/spectrum-colorpicker/spectrum.css" + ], + "base": "./node_modules/spectrum-colorpicker" + }, + { + "name": "tinymce", + "src": [ + "./node_modules/tinymce/tinymce.min.js", + "./node_modules/tinymce/plugins/**", + "./node_modules/tinymce/skins/**", + "./node_modules/tinymce/themes/**" + ], + "base": "./node_modules/tinymce" + }, + { + "name": "typeahead.js", + "src": ["./node_modules/typeahead.js/dist/typeahead.bundle.min.js"], + "base": "./node_modules/typeahead.js/dist" + }, + { + "name": "underscore", + "src": ["node_modules/underscore/underscore-min.js"], + "base": "./node_modules/underscore" + } + ]; + + // add streams for node modules + nodeModules.forEach(module => { + stream.add( + gulp.src(module.src, + { base: module.base }) + .pipe(gulp.dest(config.root + config.targets.lib + "/" + module.name)) + ); + }); + + //copy over libs which are not on npm (/lib) + stream.add( + gulp.src(config.sources.globs.lib) + .pipe(gulp.dest(config.root + config.targets.lib)) + ); + + //Copies all static assets into /root / assets folder + //css, fonts and image files + stream.add( + gulp.src(config.sources.globs.assets) + .pipe(imagemin([ + imagemin.gifsicle({interlaced: true}), + imagemin.jpegtran({progressive: true}), + imagemin.optipng({optimizationLevel: 5}), + imagemin.svgo({ + plugins: [ + {removeViewBox: true}, + {cleanupIDs: false} + ] + }) + ])) + .pipe(gulp.dest(config.root + config.targets.assets)) + ); + + // Copies all the less files related to the preview into their folder + //these are not pre-processed as preview has its own less combiler client side + stream.add( + gulp.src("src/canvasdesigner/editors/*.less") + .pipe(gulp.dest(config.root + config.targets.assets + "/less")) + ); + + // Todo: check if we need these fileSize + stream.add( + gulp.src("src/views/propertyeditors/grid/config/*.*") + .pipe(gulp.dest(config.root + config.targets.views + "/propertyeditors/grid/config")) + ); + stream.add( + gulp.src("src/views/dashboard/default/*.jpg") + .pipe(gulp.dest(config.root + config.targets.views + "/dashboard/default")) + ); + + return stream; +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/dev.js b/src/Umbraco.Web.UI.Client/gulp/tasks/dev.js new file mode 100644 index 0000000000..bca4da8c43 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/dev.js @@ -0,0 +1,10 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); +var runSequence = require('run-sequence'); + +// Dev - build the files ready for development and start watchers +gulp.task('dev', function(cb) { + runSequence(["dependencies", "js", "less", "views"], "watch", cb); +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/docs.js b/src/Umbraco.Web.UI.Client/gulp/tasks/docs.js new file mode 100644 index 0000000000..34271a018c --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/docs.js @@ -0,0 +1,55 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); + +var connect = require('gulp-connect'); +var open = require('gulp-open'); +var gulpDocs = require('gulp-ngdocs'); + +/************************** + * Build Backoffice UI API documentation + **************************/ +gulp.task('docs', [], function (cb) { + + var options = { + html5Mode: false, + startPage: '/api', + title: "Umbraco Backoffice UI API Documentation", + dest: 'docs/api', + styles: ['docs/umb-docs.css'], + image: "https://our.umbraco.com/assets/images/logo.svg" + } + + return gulpDocs.sections({ + api: { + glob: ['src/common/**/*.js', 'docs/src/api/**/*.ngdoc'], + api: true, + title: 'API Documentation' + } + }) + .pipe(gulpDocs.process(options)) + .pipe(gulp.dest('docs/api')); + cb(); +}); + +gulp.task('connect:docs', function (cb) { + connect.server({ + root: 'docs/api', + livereload: true, + fallback: 'docs/api/index.html', + port: 8880 + }); + cb(); +}); + +gulp.task('open:docs', function (cb) { + + var options = { + uri: 'http://localhost:8880/index.html' + }; + + gulp.src(__filename) + .pipe(open(options)); + cb(); +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/docserve.js b/src/Umbraco.Web.UI.Client/gulp/tasks/docserve.js new file mode 100644 index 0000000000..a402003383 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/docserve.js @@ -0,0 +1,10 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); +var runSequence = require('run-sequence'); + +// Docserve - build and open the back office documentation +gulp.task('docserve', function(cb) { + runSequence('docs', 'connect:docs', 'open:docs', cb); +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/fastdev.js b/src/Umbraco.Web.UI.Client/gulp/tasks/fastdev.js new file mode 100644 index 0000000000..888ed38fec --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/fastdev.js @@ -0,0 +1,13 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); +var runSequence = require('run-sequence'); + +// Dev - build the files ready for development and start watchers +gulp.task('fastdev', function(cb) { + + global.isProd = false; + + runSequence(["dependencies", "js", "less", "views"], "watch", cb); +}); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/js.js b/src/Umbraco.Web.UI.Client/gulp/tasks/js.js new file mode 100644 index 0000000000..e3ea0cc9d8 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/js.js @@ -0,0 +1,29 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); + +var _ = require('lodash'); +var MergeStream = require('merge-stream'); + +var processJs = require('../util/processJs'); + +/************************** + * Copies all angular JS files into their seperate umbraco.*.js file + **************************/ +gulp.task('js', function () { + + //we run multiple streams, so merge them all together + var stream = new MergeStream(); + + stream.add( + gulp.src(config.sources.globs.js) + .pipe(gulp.dest(config.root + config.targets.js)) + ); + + _.forEach(config.sources.js, function (group) { + stream.add (processJs(group.files, group.out) ); + }); + + return stream; +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/less.js b/src/Umbraco.Web.UI.Client/gulp/tasks/less.js new file mode 100644 index 0000000000..3d19716b67 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/less.js @@ -0,0 +1,20 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); + +var _ = require('lodash'); +var MergeStream = require('merge-stream'); + +var processLess = require('../util/processLess'); + +gulp.task('less', function () { + + var stream = new MergeStream(); + + _.forEach(config.sources.less, function (group) { + stream.add( processLess(group.files, group.out) ); + }); + + return stream; +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/test.js b/src/Umbraco.Web.UI.Client/gulp/tasks/test.js new file mode 100644 index 0000000000..e40d4c436a --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/test.js @@ -0,0 +1,26 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); +var karmaServer = require('karma').Server; + +/************************** + * Build tests + **************************/ + + // Karma test +gulp.task('test:unit', function() { + new karmaServer({ + configFile: __dirname + "/test/config/karma.conf.js", + keepalive: true + }) + .start(); +}); + +gulp.task('test:e2e', function() { + new karmaServer({ + configFile: __dirname + "/test/config/e2e.js", + keepalive: true + }) + .start(); +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/views.js b/src/Umbraco.Web.UI.Client/gulp/tasks/views.js new file mode 100644 index 0000000000..05246370c2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/views.js @@ -0,0 +1,25 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); + +var _ = require('lodash'); +var MergeStream = require('merge-stream'); + +gulp.task('views', function () { + + var stream = new MergeStream(); + + _.forEach(config.sources.views, function (group) { + + console.log("copying " + group.files + " to " + config.root + config.targets.views + group.folder) + + stream.add ( + gulp.src(group.files) + .pipe( gulp.dest(config.root + config.targets.views + group.folder) ) + ); + + }); + + return stream; +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/tasks/watch.js b/src/Umbraco.Web.UI.Client/gulp/tasks/watch.js new file mode 100644 index 0000000000..a5c476f7d2 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/tasks/watch.js @@ -0,0 +1,58 @@ +'use strict'; + +var config = require('../config'); +var gulp = require('gulp'); + +var _ = require('lodash'); +var MergeStream = require('merge-stream'); + +var processJs = require('../util/processJs'); + +var watch = require('gulp-watch'); + +gulp.task('watch', function () { + + var stream = new MergeStream(); + var watchInterval = 500; + + //Setup a watcher for all groups of javascript files + _.forEach(config.sources.js, function (group) { + + if(group.watch !== false){ + + stream.add( + + watch(group.files, { ignoreInitial: true, interval: watchInterval }, function (file) { + + console.info(file.path + " has changed, added to: " + group.out); + processJs(group.files, group.out); + + }) + + ); + + } + + }); + + stream.add( + //watch all less files and trigger the less task + watch(config.sources.globs.less, { ignoreInitial: true, interval: watchInterval }, function () { + gulp.run(['less']); + }) + ); + + //watch all views - copy single file changes + stream.add( + watch(config.sources.globs.views, { interval: watchInterval }) + .pipe(gulp.dest(config.root + config.targets.views)) + ); + + //watch all app js files that will not be merged - copy single file changes + stream.add( + watch(config.sources.globs.js, { interval: watchInterval }) + .pipe(gulp.dest(config.root + config.targets.js)) + ); + + return stream; +}); diff --git a/src/Umbraco.Web.UI.Client/gulp/util/handleErrors.js b/src/Umbraco.Web.UI.Client/gulp/util/handleErrors.js new file mode 100755 index 0000000000..3c32a928dd --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/util/handleErrors.js @@ -0,0 +1,18 @@ +'use strict'; + +var notify = require('gulp-notify'); + +module.exports = function(error) { + + var args = Array.prototype.slice.call(arguments); + + // Send error to notification center with gulp-notify + notify.onError({ + title: 'Compile Error', + message: '<%= error.message %>' + }).apply(this, args); + + // Keep gulp from hanging on this task + this.emit('end'); + +}; diff --git a/src/Umbraco.Web.UI.Client/gulp/util/processJs.js b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js new file mode 100644 index 0000000000..45927dc0e6 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/util/processJs.js @@ -0,0 +1,32 @@ + +var config = require('../config'); +var gulp = require('gulp'); + +var eslint = require('gulp-eslint'); +var babel = require("gulp-babel"); +var sort = require('gulp-sort'); +var concat = require('gulp-concat'); +var wrap = require("gulp-wrap-js"); + +module.exports = function(files, out) { + + var task = gulp.src(files); + + if (global.isProd === true) { + // check for js errors + task = task.pipe(eslint()); + // outputs the lint results to the console + task = task.pipe(eslint.format()); + } + + // sort files in stream by path or any custom sort comparator + task = task.pipe(babel()) + .pipe(sort()) + .pipe(concat(out)) + .pipe(wrap('(function(){\n%= body %\n})();')) + .pipe(gulp.dest(config.root + config.targets.js)); + + + return task; + +}; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/gulp/util/processLess.js b/src/Umbraco.Web.UI.Client/gulp/util/processLess.js new file mode 100644 index 0000000000..26f69865d9 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/util/processLess.js @@ -0,0 +1,33 @@ + +var config = require('../config'); +var gulp = require('gulp'); + +var postcss = require('gulp-postcss'); +var less = require('gulp-less'); +var autoprefixer = require('autoprefixer'); +var cssnano = require('cssnano'); +var cleanCss = require("gulp-clean-css"); +var rename = require('gulp-rename'); + +module.exports = function(files, out) { + + var processors = [ + autoprefixer, + cssnano({zindex: false}) + ]; + + var task = gulp.src(files) + .pipe(less()); + + + if (global.isProd === true) { + task = task.pipe(cleanCss()); + } + + task = task.pipe(postcss(processors)) + .pipe(rename(out)) + .pipe(gulp.dest(config.root + config.targets.css)); + + return task; + +}; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/gulp/util/scriptFilter.js b/src/Umbraco.Web.UI.Client/gulp/util/scriptFilter.js new file mode 100755 index 0000000000..7d8ce45f82 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/gulp/util/scriptFilter.js @@ -0,0 +1,9 @@ +'use strict'; + +var path = require('path'); + +// Filters out non .js files. Prevents +// accidental inclusion of possible hidden files +module.exports = function(name) { + return /(\.(js)$)/i.test(path.extname(name)); +}; diff --git a/src/Umbraco.Web.UI.Client/gulpfile.js b/src/Umbraco.Web.UI.Client/gulpfile.js old mode 100644 new mode 100755 index 22ac11b991..79a9d04156 --- a/src/Umbraco.Web.UI.Client/gulpfile.js +++ b/src/Umbraco.Web.UI.Client/gulpfile.js @@ -1,587 +1,16 @@ -var gulp = require('gulp'); -var watch = require('gulp-watch'); -var concat = require('gulp-concat'); -var rename = require('gulp-rename'); -var wrap = require("gulp-wrap-js"); -var sort = require('gulp-sort'); -var connect = require('gulp-connect'); -var open = require('gulp-open'); -var babel = require("gulp-babel"); -var runSequence = require('run-sequence'); -var imagemin = require('gulp-imagemin'); - -var _ = require('lodash'); -var MergeStream = require('merge-stream'); - -// js -var eslint = require('gulp-eslint'); - -//Less + css -var postcss = require('gulp-postcss'); -var less = require('gulp-less'); -var autoprefixer = require('autoprefixer'); -var cssnano = require('cssnano'); -var cleanCss = require("gulp-clean-css"); - -// Documentation -var gulpDocs = require('gulp-ngdocs'); - -// Testing -var karmaServer = require('karma').Server; - -/*************************************************************** -Helper functions -***************************************************************/ -function processJs(files, out) { - - return gulp.src(files) - // check for js errors - .pipe(eslint()) - // outputs the lint results to the console - .pipe(eslint.format()) - // sort files in stream by path or any custom sort comparator - .pipe(babel()) - .pipe(sort()) - .pipe(concat(out)) - .pipe(wrap('(function(){\n%= body %\n})();')) - .pipe(gulp.dest(root + targets.js)); - - console.log(out + " compiled"); -} - -function processLess(files, out) { - var processors = [ - autoprefixer, - cssnano({zindex: false}) - ]; - - return gulp.src(files) - .pipe(less()) - .pipe(cleanCss()) - .pipe(postcss(processors)) - .pipe(rename(out)) - .pipe(gulp.dest(root + targets.css)); - - console.log(out + " compiled"); -} - -/*************************************************************** -Paths and destinations -Each group is iterated automatically in the setup tasks below -***************************************************************/ -var sources = { - - //less files used by backoffice and preview - //processed in the less task - less: { - installer: { files: ["src/less/installer.less"], out: "installer.css" }, - nonodes: { files: ["src/less/pages/nonodes.less"], out: "nonodes.style.min.css"}, - preview: { files: ["src/less/canvas-designer.less"], out: "canvasdesigner.css" }, - umbraco: { files: ["src/less/belle.less"], out: "umbraco.css" } - }, - - //js files for backoffie - //processed in the js task - js: { - preview: { files: ["src/preview/**/*.js"], out: "umbraco.preview.js" }, - installer: { files: ["src/installer/**/*.js"], out: "umbraco.installer.js" }, - controllers: { files: ["src/{views,controllers}/**/*.controller.js"], out: "umbraco.controllers.js" }, - directives: { files: ["src/common/directives/**/*.js"], out: "umbraco.directives.js" }, - filters: { files: ["src/common/filters/**/*.js"], out: "umbraco.filters.js" }, - resources: { files: ["src/common/resources/**/*.js"], out: "umbraco.resources.js" }, - services: { files: ["src/common/services/**/*.js"], out: "umbraco.services.js" }, - security: { files: ["src/common/interceptors/**/*.js"], out: "umbraco.interceptors.js" } - }, - - //selectors for copying all views into the build - //processed in the views task - views:{ - umbraco: {files: ["src/views/**/*.html"], folder: ""}, - installer: {files: ["src/installer/steps/*.html"], folder: "install"} - }, - - //globs for file-watching - globs:{ - views: "./src/views/**/*.html", - less: "./src/less/**/*.less", - js: "./src/*.js", - lib: "./lib/**/*", - assets: "./src/assets/**" - } -}; - -var root = "../Umbraco.Web.UI/Umbraco/"; -var targets = { - js: "js/", - lib: "lib/", - views: "views/", - css: "assets/css/", - assets: "assets/" -}; - - -/************************** - * Main tasks for the project to prepare backoffice files - **************************/ - - // Build - build the files ready for production -gulp.task('build', function(cb) { - runSequence(["dependencies", "js", "less", "views"], cb); -}); - -// Dev - build the files ready for development and start watchers -gulp.task('dev', function(cb) { - runSequence(["dependencies", "js", "less", "views"], "watch", cb); -}); - -// Docserve - build and open the back office documentation -gulp.task('docserve', function(cb) { - runSequence('docs', 'connect:docs', 'open:docs', cb); -}); - -/************************** - * Task processes and copies all dependencies, either installed by npm or stored locally in the project - **************************/ -gulp.task('dependencies', function () { - - //as we do multiple things in this task, we merge the multiple streams - var stream = new MergeStream(); - - // Pick the dependencies we need from each package - // so we don't just ship with a lot of files that aren't needed - const nodeModules = [ - { - "name": "ace-builds", - "src": [ - "./node_modules/ace-builds/src-min-noconflict/ace.js", - "./node_modules/ace-builds/src-min-noconflict/ext-language_tools.js", - "./node_modules/ace-builds/src-min-noconflict/ext-searchbox.js", - "./node_modules/ace-builds/src-min-noconflict/ext-settings_menu.js", - "./node_modules/ace-builds/src-min-noconflict/snippets/text.js", - "./node_modules/ace-builds/src-min-noconflict/snippets/javascript.js", - "./node_modules/ace-builds/src-min-noconflict/snippets/css.js", - "./node_modules/ace-builds/src-min-noconflict/theme-chrome.js", - "./node_modules/ace-builds/src-min-noconflict/mode-razor.js", - "./node_modules/ace-builds/src-min-noconflict/mode-javascript.js", - "./node_modules/ace-builds/src-min-noconflict/mode-css.js", - "./node_modules/ace-builds/src-min-noconflict/worker-javascript.js", - "./node_modules/ace-builds/src-min-noconflict/worker-css.js" - ], - "base": "./node_modules/ace-builds" - }, - { - "name": "angular", - "src": ["./node_modules/angular/angular.js"], - "base": "./node_modules/angular" - }, - { - "name": "angular-cookies", - "src": ["./node_modules/angular-cookies/angular-cookies.js"], - "base": "./node_modules/angular-cookies" - }, - { - "name": "angular-dynamic-locale", - "src": [ - "./node_modules/angular-dynamic-locale/dist/tmhDynamicLocale.min.js", - "./node_modules/angular-dynamic-locale/dist/tmhDynamicLocale.min.js.map" - ], - "base": "./node_modules/angular-dynamic-locale/dist" - }, - { - "name": "angular-sanitize", - "src": ["./node_modules/angular-sanitize/angular-sanitize.js"], - "base": "./node_modules/angular-sanitize" - }, - { - "name": "angular-touch", - "src": ["./node_modules/angular-touch/angular-touch.js"], - "base": "./node_modules/angular-touch" - }, - { - "name": "angular-ui-sortable", - "src": ["./node_modules/angular-ui-sortable/dist/sortable.js"], - "base": "./node_modules/angular-ui-sortable/dist" - }, - { - "name": "angular-route", - "src": ["./node_modules/angular-route/angular-route.js"], - "base": "./node_modules/angular-route" - }, - { - "name": "angular-animate", - "src": ["./node_modules/angular-animate/angular-animate.js"], - "base": "./node_modules/angular-animate" - }, - { - "name": "angular-i18n", - "src": [ - "./node_modules/angular-i18n/angular-i18n.js", - "./node_modules/angular-i18n/angular-locale_*.js" - ], - "base": "./node_modules/angular-i18n" - }, - { - "name": "angular-local-storage", - "src": [ - "./node_modules/angular-local-storage/dist/angular-local-storage.min.js", - "./node_modules/angular-local-storage/dist/angular-local-storage.min.js.map" - ], - "base": "./node_modules/angular-local-storage/dist" - }, - { - "name": "angular-messages", - "src": ["./node_modules/angular-messages/angular-messages.js"], - "base": "./node_modules/angular-messages" - }, - { - "name": "angular-mocks", - "src": ["./node_modules/angular-mocks/angular-mocks.js"], - "base": "./node_modules/angular-mocks" - }, - { - "name": "animejs", - "src": ["./node_modules/animejs/anime.min.js"], - "base": "./node_modules/animejs" - }, - { - "name": "bootstrap-social", - "src": ["./node_modules/bootstrap-social/bootstrap-social.css"], - "base": "./node_modules/bootstrap-social" - }, - - { - "name": "angular-chart.js", - "src": ["./node_modules/angular-chart.js/dist/angular-chart.min.js"], - "base": "./node_modules/angular-chart.js/dist" - }, - { - "name": "chart.js", - "src": ["./node_modules/chart.js/dist/chart.min.js"], - "base": "./node_modules/chart.js/dist" - }, - { - "name": "clipboard", - "src": ["./node_modules/clipboard/dist/clipboard.min.js"], - "base": "./node_modules/clipboard/dist" - }, - { - "name": "jsdiff", - "src": ["./node_modules/diff/dist/diff.min.js"], - "base": "./node_modules/diff/dist" - }, - { - "name": "flatpickr", - "src": [ - "./node_modules/flatpickr/dist/flatpickr.js", - "./node_modules/flatpickr/dist/flatpickr.css" - ], - "base": "./node_modules/flatpickr/dist" - }, - { - "name": "font-awesome", - "src": [ - "./node_modules/font-awesome/fonts/*", - "./node_modules/font-awesome/css/font-awesome.min.css" - ], - "base": "./node_modules/font-awesome" - }, - { - "name": "jquery", - "src": [ - "./node_modules/jquery/dist/jquery.min.js", - "./node_modules/jquery/dist/jquery.min.map" - ], - "base": "./node_modules/jquery/dist" - }, - { - "name": "jquery-ui", - "src": ["./node_modules/jquery-ui-dist/jquery-ui.min.js"], - "base": "./node_modules/jquery-ui-dist" - }, - { - "name": "jquery-ui-touch-punch", - "src": ["./node_modules/jquery-ui-touch-punch/jquery.ui.touch-punch.min.js"], - "base": "./node_modules/jquery-ui-touch-punch" - }, - { - "name": "lazyload-js", - "src": ["./node_modules/lazyload-js/lazyload.min.js"], - "base": "./node_modules/lazyload-js" - }, - { - "name": "moment", - "src": ["./node_modules/moment/min/moment.min.js"], - "base": "./node_modules/moment/min" - }, - { - "name": "moment", - "src": ["./node_modules/moment/locale/*.js"], - "base": "./node_modules/moment/locale" - }, - { - "name": "ng-file-upload", - "src": ["./node_modules/ng-file-upload/dist/ng-file-upload.min.js"], - "base": "./node_modules/ng-file-upload/dist" - }, - { - "name": "nouislider", - "src": [ - "./node_modules/nouislider/distribute/nouislider.min.js", - "./node_modules/nouislider/distribute/nouislider.min.css" - ], - "base": "./node_modules/nouislider/distribute" - }, - { - "name": "signalr", - "src": ["./node_modules/signalr/jquery.signalR.js"], - "base": "./node_modules/signalr" - }, - { - "name": "spectrum", - "src": [ - "./node_modules/spectrum-colorpicker/spectrum.js", - "./node_modules/spectrum-colorpicker/spectrum.css" - ], - "base": "./node_modules/spectrum-colorpicker" - }, - { - "name": "tinymce", - "src": [ - "./node_modules/tinymce/tinymce.min.js", - "./node_modules/tinymce/plugins/**", - "./node_modules/tinymce/skins/**", - "./node_modules/tinymce/themes/**" - ], - "base": "./node_modules/tinymce" - }, - { - "name": "typeahead.js", - "src": ["./node_modules/typeahead.js/dist/typeahead.bundle.min.js"], - "base": "./node_modules/typeahead.js/dist" - }, - { - "name": "underscore", - "src": ["node_modules/underscore/underscore-min.js"], - "base": "./node_modules/underscore" - } - ]; - - // add streams for node modules - nodeModules.forEach(module => { - stream.add( - gulp.src(module.src, - { base: module.base }) - .pipe(gulp.dest(root + targets.lib + "/" + module.name)) - ); - }); - - //copy over libs which are not on npm (/lib) - stream.add( - gulp.src(sources.globs.lib) - .pipe(gulp.dest(root + targets.lib)) - ); - - //Copies all static assets into /root / assets folder - //css, fonts and image files - stream.add( - gulp.src(sources.globs.assets) - .pipe(imagemin([ - imagemin.gifsicle({interlaced: true}), - imagemin.jpegtran({progressive: true}), - imagemin.optipng({optimizationLevel: 5}), - imagemin.svgo({ - plugins: [ - {removeViewBox: true}, - {cleanupIDs: false} - ] - }) - ])) - .pipe(gulp.dest(root + targets.assets)) - ); - - // Copies all the less files related to the preview into their folder - //these are not pre-processed as preview has its own less combiler client side - stream.add( - gulp.src("src/canvasdesigner/editors/*.less") - .pipe(gulp.dest(root + targets.assets + "/less")) - ); - - // Todo: check if we need these fileSize - stream.add( - gulp.src("src/views/propertyeditors/grid/config/*.*") - .pipe(gulp.dest(root + targets.views + "/propertyeditors/grid/config")) - ); - stream.add( - gulp.src("src/views/dashboard/default/*.jpg") - .pipe(gulp.dest(root + targets.views + "/dashboard/default")) - ); - - return stream; -}); - - -/************************** - * Copies all angular JS files into their seperate umbraco.*.js file - **************************/ -gulp.task('js', function () { - - //we run multiple streams, so merge them all together - var stream = new MergeStream(); - - stream.add( - gulp.src(sources.globs.js) - .pipe(gulp.dest(root + targets.js)) - ); - - _.forEach(sources.js, function (group) { - stream.add (processJs(group.files, group.out) ); - }); - - return stream; -}); - -gulp.task('less', function () { - - var stream = new MergeStream(); - - _.forEach(sources.less, function (group) { - stream.add( processLess(group.files, group.out) ); - }); - - return stream; -}); - - -gulp.task('views', function () { - - var stream = new MergeStream(); - - _.forEach(sources.views, function (group) { - - console.log("copying " + group.files + " to " + root + targets.views + group.folder) - - stream.add ( - gulp.src(group.files) - .pipe( gulp.dest(root + targets.views + group.folder) ) - ); - - }); - - return stream; -}); - - -gulp.task('watch', function () { - - var stream = new MergeStream(); - var watchInterval = 500; - - //Setup a watcher for all groups of javascript files - _.forEach(sources.js, function (group) { - - if(group.watch !== false){ - - stream.add( - - watch(group.files, { ignoreInitial: true, interval: watchInterval }, function (file) { - - console.info(file.path + " has changed, added to: " + group.out); - processJs(group.files, group.out); - - }) - - ); - - } - - }); - - stream.add( - //watch all less files and trigger the less task - watch(sources.globs.less, { ignoreInitial: true, interval: watchInterval }, function () { - gulp.run(['less']); - }) - ); - - //watch all views - copy single file changes - stream.add( - watch(sources.globs.views, { interval: watchInterval }) - .pipe(gulp.dest(root + targets.views)) - ); - - //watch all app js files that will not be merged - copy single file changes - stream.add( - watch(sources.globs.js, { interval: watchInterval }) - .pipe(gulp.dest(root + targets.js)) - ); - - return stream; -}); - -/************************** - * Build Backoffice UI API documentation - **************************/ -gulp.task('docs', [], function (cb) { - - var options = { - html5Mode: false, - startPage: '/api', - title: "Umbraco Backoffice UI API Documentation", - dest: 'docs/api', - styles: ['docs/umb-docs.css'], - image: "https://our.umbraco.com/assets/images/logo.svg" - } - - return gulpDocs.sections({ - api: { - glob: ['src/common/**/*.js', 'docs/src/api/**/*.ngdoc'], - api: true, - title: 'API Documentation' - } - }) - .pipe(gulpDocs.process(options)) - .pipe(gulp.dest('docs/api')); - cb(); -}); - -gulp.task('connect:docs', function (cb) { - connect.server({ - root: 'docs/api', - livereload: true, - fallback: 'docs/api/index.html', - port: 8880 - }); - cb(); -}); - -gulp.task('open:docs', function (cb) { - - var options = { - uri: 'http://localhost:8880/index.html' - }; - - gulp.src(__filename) - .pipe(open(options)); - cb(); -}); - -/************************** - * Build tests - **************************/ - - // Karma test -gulp.task('test:unit', function() { - new karmaServer({ - configFile: __dirname + "/test/config/karma.conf.js", - keepalive: true - }) - .start(); -}); - -gulp.task('test:e2e', function() { - new karmaServer({ - configFile: __dirname + "/test/config/e2e.js", - keepalive: true - }) - .start(); -}); +'use strict'; + +/* + * gulpfile.js + * =========== + * Rather than manage one giant configuration file responsible + * for creating multiple tasks, each task has been broken out into + * its own file in gulp/tasks. Any file in that folder gets automatically + * required by the loop in ./gulp/index.js (required below). + * + * To add a new task, simply add a new task file to gulp/tasks. + */ + +global.isProd = true; + +require('./gulp'); diff --git a/src/Umbraco.Web.UI.Client/package-lock.json b/src/Umbraco.Web.UI.Client/package-lock.json index f6d915eede..fe657ae470 100644 --- a/src/Umbraco.Web.UI.Client/package-lock.json +++ b/src/Umbraco.Web.UI.Client/package-lock.json @@ -5115,6 +5115,12 @@ "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", "dev": true }, + "fs": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/fs/-/fs-0.0.2.tgz", + "integrity": "sha1-4fJE7zkzwbKmS9R5kTYGDQ9ZFPg=", + "dev": true + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -6119,6 +6125,12 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, "gulp": { "version": "3.9.1", "resolved": "http://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", @@ -6916,6 +6928,102 @@ } } }, + "gulp-notify": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/gulp-notify/-/gulp-notify-3.2.0.tgz", + "integrity": "sha512-qEocs1UVoDKKUjfsxJNMNwkRla0PbsyJwsqNNXpzYWsLQ29LhxRMY3wnTGZcc4hMHtalnvah/Dwlwb4NijH/0A==", + "dev": true, + "requires": { + "ansi-colors": "^1.0.1", + "fancy-log": "^1.3.2", + "lodash.template": "^4.4.0", + "node-notifier": "^5.2.1", + "node.extend": "^2.0.0", + "plugin-error": "^0.1.2", + "through2": "^2.0.3" + }, + "dependencies": { + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "^1.1.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + }, + "node.extend": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-2.0.2.tgz", + "integrity": "sha512-pDT4Dchl94/+kkgdwyS2PauDFjZG0Hk0IcHIB+LkW27HLDtdoeMxHTxZh39DYbPP8UflWXWj9JcdDozF+YDOpQ==", + "dev": true, + "requires": { + "has": "^1.0.3", + "is": "^3.2.1" + } + }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + } + } + } + }, "gulp-open": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/gulp-open/-/gulp-open-3.0.1.tgz", @@ -9368,6 +9476,18 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, + "node-notifier": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.3.0.tgz", + "integrity": "sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, "node-releases": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.0.5.tgz", @@ -14124,6 +14244,12 @@ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, "sigmund": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", diff --git a/src/Umbraco.Web.UI.Client/package.json b/src/Umbraco.Web.UI.Client/package.json index e35fdc3442..61bdb88f17 100644 --- a/src/Umbraco.Web.UI.Client/package.json +++ b/src/Umbraco.Web.UI.Client/package.json @@ -2,7 +2,10 @@ "private": true, "scripts": { "test": "karma start test/config/karma.conf.js --singlerun", - "build": "gulp" + "build": "gulp build", + "dev": "gulp dev", + "fastdev": "gulp fastdev", + "docs": "gulp docs" }, "dependencies": { "ace-builds": "1.4.2", @@ -62,6 +65,7 @@ "gulp-watch": "5.0.1", "gulp-wrap": "0.14.0", "gulp-wrap-js": "0.4.1", + "gulp-notify": "^3.0.0", "jasmine-core": "3.3.0", "karma": "3.1.1", "karma-jasmine": "2.0.1", @@ -70,6 +74,7 @@ "lodash": "4.17.11", "marked": "^0.5.2", "merge-stream": "1.0.1", - "run-sequence": "2.2.1" + "run-sequence": "2.2.1", + "fs": "0.0.2" } } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js index 1987c897f0..99d6b939e0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/umbvariantcontenteditors.directive.js @@ -215,9 +215,15 @@ * @param {any} selectedVariant */ function openSplitView(selectedVariant) { - var selectedCulture = selectedVariant.language.culture; + //Find the whole variant model based on the culture that was chosen + var variant = _.find(vm.content.variants, function (v) { + return v.language.culture === selectedCulture; + }); + + insertVariantEditor(vm.editors.length, initVariant(variant, vm.editors.length)); + //only the content app can be selected since no other apps are shown, and because we copy all of these apps //to the "editors" we need to update this across all editors for (var e = 0; e < vm.editors.length; e++) { @@ -233,13 +239,6 @@ } } - //Find the whole variant model based on the culture that was chosen - var variant = _.find(vm.content.variants, function (v) { - return v.language.culture === selectedCulture; - }); - - insertVariantEditor(vm.editors.length, initVariant(variant, vm.editors.length)); - //TODO: hacking animation states - these should hopefully be easier to do when we upgrade angular editor.collapsed = true; editor.loading = true; @@ -260,6 +259,8 @@ vm.editors.splice(editorIndex, 1); //remove variant from open variants vm.openVariants.splice(editorIndex, 1); + //update the current culture to reflect the last open variant (closing the split view corresponds to selecting the other variant) + $location.search("cculture", vm.openVariants[0]); splitViewChanged(); }, 400); } @@ -270,7 +271,7 @@ * @param {any} editorIndex The index of the editor being changed */ function selectVariant(variant, editorIndex) { - + // prevent variants already open in a split view to be opened if(vm.openVariants.indexOf(variant.language.culture) !== -1) { return; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js index 56a18a217e..2bc1c636b5 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umbGenerateAlias.directive.js @@ -44,6 +44,7 @@ the directive will use {@link umbraco.directives.directive:umbLockedField umbLoc @param {string} alias (binding): The model where the alias is bound. @param {string} aliasFrom (binding): The model to generate the alias from. +@param {string} validationPosition (binding): The position of the validation. Set to 'left' or 'right'. @param {boolean=} enableLock (binding): Set to true to add a lock next to the alias from where it can be unlocked and changed. **/ @@ -57,6 +58,7 @@ angular.module("umbraco.directives") alias: '=', aliasFrom: '=', enableLock: '=?', + validationPosition: '=?', serverValidationField: '@' }, link: function (scope, element, attrs, ctrl) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblockedfield.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblockedfield.directive.js index cc5a1eb2b1..f19e2c810b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/umblockedfield.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/umblockedfield.directive.js @@ -40,6 +40,7 @@ Use this directive to render a value with a lock next to it. When the lock is cl @param {boolean=} locked (binding): true by default. Set to false to unlock the text. @param {string=} placeholderText (binding): If ngModel is empty this text will be shown. @param {string=} regexValidation (binding): Set a regex expression for validation of the field. +@param {string} validationPosition (binding): The position of the validation. Set to 'left' or 'right'. @param {string=} serverValidationField (attribute): Set a server validation field. **/ @@ -70,7 +71,11 @@ Use this directive to render a value with a lock next to it. When the lock is cl // if locked state is not defined as an attr set default state if (scope.placeholderText === undefined || scope.placeholderText === null) { scope.placeholderText = "Enter value..."; - } + } + + if (scope.validationPosition === undefined || scope.validationPosition === null) { + scope.validationPosition = "left"; + } } @@ -93,9 +98,10 @@ Use this directive to render a value with a lock next to it. When the lock is cl templateUrl: 'views/components/umb-locked-field.html', scope: { ngModel: "=", - locked: "=?", + locked: "=?", placeholderText: "=?", - regexValidation: "=?", + regexValidation: "=?", + validationPosition: "=?", serverValidationField: "@" }, link: link diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js index 9724c222b6..6bc7855528 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/resources/tree.mocks.js @@ -11,24 +11,24 @@ angular.module('umbraco.mocks'). var menu = [ { name: "Create", cssclass: "plus", alias: "create", metaData: {} }, - { seperator: true, name: "Delete", cssclass: "remove", alias: "delete", metaData: {} }, + { separator: true, name: "Delete", cssclass: "remove", alias: "delete", metaData: {} }, { name: "Move", cssclass: "move", alias: "move", metaData: {} }, { name: "Copy", cssclass: "copy", alias: "copy", metaData: {} }, { name: "Sort", cssclass: "sort", alias: "sort", metaData: {} }, - { seperator: true, name: "Publish", cssclass: "globe", alias: "publish", metaData: {} }, + { separator: true, name: "Publish", cssclass: "globe", alias: "publish", metaData: {} }, { name: "Rollback", cssclass: "undo", alias: "rollback", metaData: {} }, - { seperator: true, name: "Permissions", cssclass: "lock", alias: "permissions", metaData: {} }, + { separator: true, name: "Permissions", cssclass: "lock", alias: "permissions", metaData: {} }, { name: "Audit Trail", cssclass: "time", alias: "audittrail", metaData: {} }, { name: "Notifications", cssclass: "envelope", alias: "notifications", metaData: {} }, - { seperator: true, name: "Hostnames", cssclass: "home", alias: "hostnames", metaData: {} }, + { separator: true, name: "Hostnames", cssclass: "home", alias: "hostnames", metaData: {} }, { name: "Public Access", cssclass: "group", alias: "publicaccess", metaData: {} }, - { seperator: true, name: "Reload", cssclass: "refresh", alias: "users", metaData: {} }, + { separator: true, name: "Reload", cssclass: "refresh", alias: "users", metaData: {} }, - { seperator: true, name: "Empty Recycle Bin", cssclass: "trash", alias: "emptyrecyclebin", metaData: {} } + { separator: true, name: "Empty Recycle Bin", cssclass: "trash", alias: "emptyrecyclebin", metaData: {} } ]; var result = { @@ -94,7 +94,7 @@ angular.module('umbraco.mocks'). jsAction: "umbracoMenuActions.CreateChildEntity" } }, - { seperator: true, name: "Reload", cssclass: "refresh", alias: "users", metaData: {} } + { separator: true, name: "Reload", cssclass: "refresh", alias: "users", metaData: {} } ]; return [200, menu, null]; diff --git a/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js b/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js index ec1175ab6c..1cf5266c83 100644 --- a/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js +++ b/src/Umbraco.Web.UI.Client/src/common/mocks/services/localization.mocks.js @@ -453,13 +453,11 @@ angular.module('umbraco.mocks'). "notifications_notifications": "Notifications", "packager_chooseLocalPackageText": " Choose Package from your machine, by clicking the Browse
button and locating the package. Umbraco packages usually have a '.umb' or '.zip' extension. ", "packager_packageAuthor": "Author", - "packager_packageDemonstration": "Demonstration", "packager_packageDocumentation": "Documentation", "packager_packageMetaData": "Package meta data", "packager_packageName": "Package name", "packager_packageNoItemsHeader": "Package doesn't contain any items", "packager_packageNoItemsText": "This package file doesn't contain any items to uninstall.

You can safely remove this from the system by clicking 'uninstall package' below.", - "packager_packageNoUpgrades": "No upgrades available", "packager_packageOptions": "Package options", "packager_packageReadme": "Package readme", "packager_packageRepository": "Package repository", @@ -468,12 +466,7 @@ angular.module('umbraco.mocks'). "packager_packageUninstalledText": "The package was successfully uninstalled", "packager_packageUninstallHeader": "Uninstall package", "packager_packageUninstallText": "You can unselect items you do not wish to remove, at this time, below. When you click 'confirm uninstall' all checked-off items will be removed.
Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, so uninstall with caution. If in doubt, contact the package author.", - "packager_packageUpgradeDownload": "Download update from the repository", - "packager_packageUpgradeHeader": "Upgrade package", - "packager_packageUpgradeInstructions": "Upgrade instructions", - "packager_packageUpgradeText": " There's an upgrade available for this package. You can download it directly from the Umbraco package repository.", "packager_packageVersion": "Package version", - "packager_viewPackageWebsite": "View package website", "paste_doNothing": "Paste with full formatting (Not recommended)", "paste_errorMessage": "The text you're trying to paste contains special characters or formatting. This could be caused by copying text from Microsoft Word. Umbraco can remove special characters or formatting automatically, so the pasted content will be more suitable for the web.", "paste_removeAll": "Paste as raw text without any formatting at all", @@ -640,7 +633,7 @@ angular.module('umbraco.mocks'). "templateEditor_urlEncodeHelp": "Will format special characters in URLs", "templateEditor_usedIfAllEmpty": "Will only be used when the field values above are empty", "templateEditor_usedIfEmpty": "This field will only be used if the primary field is empty", - "templateEditor_withTime": "Yes, with time. Seperator: ", + "templateEditor_withTime": "Yes, with time. Separator: ", "translation_details": "Translation details", "translation_DownloadXmlDTD": "Download xml DTD", "translation_fields": "Fields", diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js index 0d74d0fdd3..7519341327 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/package.resource.js @@ -175,7 +175,17 @@ function packageResource($q, $http, umbDataFormatter, umbRequestHelper) { umbRequestHelper.getApiUrl( "packageApiBaseUrl", "GetCreatedPackageById", - [{ id: id }])), + { id: id })), + 'Failed to get package'); + }, + + getInstalledById: function (id) { + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "packageApiBaseUrl", + "GetInstalledPackageById", + { id: id })), 'Failed to get package'); }, diff --git a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js index 47e5a24180..1258ec4099 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/contenteditinghelper.service.js @@ -421,7 +421,7 @@ function contentEditingHelper(fileManager, $q, $location, $routeParams, notifica */ reBindChangedProperties: function (origContent, savedContent) { - //TODO: We should probably split out this logic to deal with media/members seperately to content + //TODO: We should probably split out this logic to deal with media/members separately to content //a method to ignore built-in prop changes var shouldIgnore = function (propName) { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/tree/umb-tree.less b/src/Umbraco.Web.UI.Client/src/less/components/tree/umb-tree.less index 4705b8cc3e..bd493cf0d3 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/tree/umb-tree.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/tree/umb-tree.less @@ -125,6 +125,8 @@ body.touch .umb-tree { position: inherit; display: inherit; + list-style: none; + h6 { padding: 10px 0 10px 20px; font-weight: inherit; @@ -137,7 +139,15 @@ body.touch .umb-tree { } &-item { - padding-left: 20px; + padding: 4px 0; + + &:hover { + background-color: @gray-10; + } + + &-link { + display: block; + } } &-link { diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-breadcrumbs.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-breadcrumbs.less index 0cb7bc9fe4..ba04069c6b 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-breadcrumbs.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-breadcrumbs.less @@ -28,7 +28,7 @@ color: @black; } -.umb-breadcrumbs__seperator { +.umb-breadcrumbs__separator { position: relative; top: 1px; margin-left: 5px; @@ -41,4 +41,4 @@ input.umb-breadcrumbs__add-ancestor { margin-top: -2px; margin-left: 3px; width: 100px; -} \ No newline at end of file +} diff --git a/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less b/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less index 9001f1d473..8d9ae86ce7 100644 --- a/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less +++ b/src/Umbraco.Web.UI.Client/src/less/components/umb-locked-field.less @@ -38,6 +38,7 @@ input.umb-locked-field__input { transition: color 0.25s; padding: 0; height: auto; + max-width: 300px; } input.umb-locked-field__input:focus { diff --git a/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less b/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less index 417447c3dc..9b4bac723b 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms/umb-validation-label.less @@ -1,46 +1,67 @@ .umb-validation-label { - position: absolute; - top: 27px; - width: 200px; - padding: 1px 5px; - background: @red; - color: @white; - font-size: 11px; - line-height: 1.5em; + position: absolute; + top: 27px; + min-width: 100px; + max-width: 200px; + padding: 1px 5px; + background: @red; + color: @white; + font-size: 11px; + line-height: 1.5em; } .umb-validation-label:after { - bottom: 100%; - left: 10px; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(255, 255, 255, 0); - border-bottom-color: @red; - border-width: 4px; - margin-left: -4px; + bottom: 100%; + left: 10px; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-color: rgba(255, 255, 255, 0); + border-bottom-color: @red; + border-width: 4px; + margin-left: -4px; +} + +.umb-validation-label.-left { + left: 0; + right: auto; + + &:after { + left: 10px; + right: auto; + } +} + +.umb-validation-label.-right { + right: 0; + left: auto; + + &:after { + right: 10px; + left: auto; + } } .umb-validation-label.-arrow-left { - margin-left: 10px; + margin-left: 10px; } .umb-validation-label.-arrow-left:after { - right: 100%; - top: 50%; - left: auto; - bottom: auto; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - border-color: rgba(255, 255, 255, 0); - border-right-color: @red; - border-width: 4px; - margin-top: -4px; + right: 100%; + top: 50%; + left: auto; + bottom: auto; + border: solid transparent; + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + border-color: rgba(255, 255, 255, 0); + border-right-color: @red; + border-width: 4px; + margin-top: -4px; } diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index 3d9df196d7..ae930d6fb0 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -373,10 +373,6 @@ margin-bottom: 0; } -.umb-panel-header-alias .umb-validation-label:after { - visibility: hidden; -} - .umb-panel-header-alias .umb-locked-field:after { display: none; } diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index 2d8ad46371..c2d3ea2df8 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -149,14 +149,22 @@ app.config(function ($routeProvider) { .when('/:section/:tree/:method?', { //This allows us to dynamically change the template for this route since you cannot inject services into the templateUrl method. template: "
", - //This controller will execute for this route, then we replace the template dynamnically based on the current tree. - controller: function ($scope, $route, $routeParams, treeService) { + //This controller will execute for this route, then we replace the template dynamically based on the current tree. + controller: function ($scope, $routeParams, treeService) { if (!$routeParams.method) { $scope.templateUrl = "views/common/dashboard.html"; + return; } - // Here we need to figure out if this route is for a package tree and if so then we need + //special case for the package section + var packagePages = ["edit", "options"]; + if ($routeParams.section.toLowerCase() === "packages" && $routeParams.tree.toLowerCase() === "packages" && packagePages.indexOf($routeParams.method.toLowerCase()) === -1) { + $scope.templateUrl = "views/packages/overview.html"; + return; + } + + // Here we need to figure out if this route is for a user's package tree and if so then we need // to change it's convention view path to: // /App_Plugins/{mypackage}/backoffice/{treetype}/{method}.html diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js index 4faa5fd03a..6057b671bd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/linkpicker/linkpicker.controller.js @@ -33,31 +33,51 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController", $scope.showTarget = $scope.model.hideTarget !== true; + // this ensures that we only sync the tree once and only when it's ready + var oneTimeTreeSync = { + executed: false, + treeReady: false, + sync: function () { + // don't run this if: + // - it was already run once + // - the tree isn't ready yet + // - the model path hasn't been loaded yet + if (this.executed || !this.treeReady || !($scope.model.target && $scope.model.target.path)) { + return; + } + + this.executed = true; + // sync the tree to the model path + $scope.dialogTreeApi.syncTree({ + path: $scope.model.target.path, + tree: "content" + }); + } + }; + if (dialogOptions.currentTarget) { - $scope.model.target = dialogOptions.currentTarget; + // clone the current target so we don't accidentally update the caller's model while manipulating $scope.model.target + $scope.model.target = angular.copy(dialogOptions.currentTarget); //if we have a node ID, we fetch the current node to build the form data if ($scope.model.target.id || $scope.model.target.udi) { //will be either a udi or an int var id = $scope.model.target.udi ? $scope.model.target.udi : $scope.model.target.id; - if (!$scope.model.target.path) { - + // is it a content link? + if (!$scope.model.target.isMedia) { + // get the content path entityResource.getPath(id, "Document").then(function (path) { $scope.model.target.path = path; - //now sync the tree to this path - $scope.dialogTreeApi.syncTree({ - path: $scope.model.target.path, - tree: "content" - }); + oneTimeTreeSync.sync(); + }); + + // get the content properties to build the anchor name list + contentResource.getById(id).then(function (resp) { + $scope.anchorValues = tinyMceService.getAnchorNames(JSON.stringify(resp.properties)); + $scope.model.target.url = resp.urls[0]; }); } - - // if a link exists, get the properties to build the anchor name list - contentResource.getById(id).then(function (resp) { - $scope.anchorValues = tinyMceService.getAnchorNames(JSON.stringify(resp.properties)); - $scope.model.target.url = resp.urls[0]; - }); } else if ($scope.model.target.url.length) { // a url but no id/udi indicates an external link - trim the url to remove the anchor/qs // only do the substring if there's a # or a ? @@ -72,6 +92,11 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController", $scope.anchorValues = dialogOptions.anchors; } + function treeLoadedHandler(args) { + oneTimeTreeSync.treeReady = true; + oneTimeTreeSync.sync(); + } + function nodeSelectHandler(args) { if (args && args.event) { args.event.preventDefault(); @@ -127,6 +152,12 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController", $scope.model.target.url = mediaHelper.resolveFile(media); editorService.close(); + + // make sure the content tree has nothing highlighted + $scope.dialogTreeApi.syncTree({ + path: "-1", + tree: "content" + }); }, close: function() { editorService.close(); @@ -146,7 +177,7 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController", // method to select a search result $scope.selectResult = function (evt, result) { result.selected = result.selected === true ? false : true; - nodeSelectHandler(evt, { + nodeSelectHandler({ event: evt, node: result }); @@ -159,6 +190,7 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController", }; $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeLoaded(treeLoadedHandler); $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); } @@ -166,7 +198,7 @@ angular.module("umbraco").controller("Umbraco.Editors.LinkPickerController", // Mini list view $scope.selectListViewNode = function (node) { node.selected = node.selected === true ? false : true; - nodeSelectHandler({}, { + nodeSelectHandler({ node: node }); }; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html index cac412df8b..b5dd23b1fd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/mediapicker/mediapicker.html @@ -55,12 +55,12 @@
  • Media - / + /
  • {{item.name}} - / + /
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js index 1a4cc2b930..346bddf00f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/infiniteeditors/treepicker/treepicker.controller.js @@ -54,6 +54,7 @@ angular.module("umbraco").controller("Umbraco.Editors.TreePickerController", vm.toggleLanguageSelector = toggleLanguageSelector; vm.selectLanguage = selectLanguage; vm.onSearchResults = onSearchResults; + vm.selectResult = selectResult; vm.hideSearch = hideSearch; vm.closeMiniListView = closeMiniListView; vm.selectListViewNode = selectListViewNode; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-contextmenu.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-contextmenu.html index 2e7048eefa..92da12c423 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-contextmenu.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-contextmenu.html @@ -5,7 +5,7 @@
    diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html index 267d805d0a..3754b66c53 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-header.html @@ -45,6 +45,7 @@ alias="$parent.alias" alias-from="$parent.name" enable-lock="true" + validation-position="'right'" server-validation-field="Alias"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-menu.html b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-menu.html index 032e4cd6c3..54a33a705f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-menu.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/editor/umb-editor-menu.html @@ -9,7 +9,7 @@ - + {{action.name}} diff --git a/src/Umbraco.Web.UI.Client/src/views/components/media/umb-media-node-info.html b/src/Umbraco.Web.UI.Client/src/views/components/media/umb-media-node-info.html index 2e09fbfa3b..4004c2b958 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/media/umb-media-node-info.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/media/umb-media-node-info.html @@ -5,16 +5,16 @@ -
    -
    Required alias
    -
    Invalid alias
    -
    {{lockedFieldForm.lockedField.errorMsg}}
    +
    + Required alias +
    +
    + Invalid alias +
    +
    {{lockedFieldForm.lockedField.errorMsg}} +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js index a64d6eed66..2c615db4dc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.restore.controller.js @@ -1,26 +1,91 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController", - function ($scope, relationResource, mediaResource, navigationService, appState, treeService, localizationService) { + function ($scope, relationResource, mediaResource, entityResource, navigationService, appState, treeService, userService) { $scope.source = _.clone($scope.currentNode); $scope.error = null; - $scope.success = false; $scope.loading = true; + $scope.moving = false; + $scope.success = false; + + $scope.dialogTreeApi = {}; + $scope.searchInfo = { + showSearch: false, + results: [], + selectedSearchResults: [] + } + $scope.treeModel = { + hideHeader: false + } + userService.getCurrentUser().then(function (userData) { + $scope.treeModel.hideHeader = userData.startContentIds.length > 0 && userData.startContentIds.indexOf(-1) == -1; + }); + + function nodeSelectHandler(args) { + + if (args && args.event) { + args.event.preventDefault(); + args.event.stopPropagation(); + } + + if ($scope.target) { + //un-select if there's a current one selected + $scope.target.selected = false; + } + + $scope.target = args.node; + $scope.target.selected = true; + + } + + function nodeExpandedHandler(args) { + // open mini list view for list views + if (args.node.metaData.isContainer) { + openMiniListView(args.node); + } + } + + $scope.hideSearch = function () { + $scope.searchInfo.showSearch = false; + $scope.searchInfo.results = []; + } + + // method to select a search result + $scope.selectResult = function (evt, result) { + result.selected = result.selected === true ? false : true; + nodeSelectHandler(evt, { event: evt, node: result }); + }; + + //callback when there are search results + $scope.onSearchResults = function (results) { + $scope.searchInfo.results = results; + $scope.searchInfo.showSearch = true; + }; + + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + } + + // Mini list view + $scope.selectListViewNode = function (node) { + node.selected = node.selected === true ? false : true; + nodeSelectHandler({}, { node: node }); + }; + + $scope.closeMiniListView = function () { + $scope.miniListView = undefined; + }; + + function openMiniListView(node) { + $scope.miniListView = node; + } relationResource.getByChildId($scope.source.id, "relateParentDocumentOnDelete").then(function (data) { $scope.loading = false; if (!data.length) { - localizationService.localizeMany(["recycleBin_itemCannotBeRestored", "recycleBin_noRestoreRelation"]) - .then(function(values) { - $scope.success = false; - $scope.error = { - errorMsg: values[0], - data: { - Message: values[1] - } - } - }); + $scope.moving = true; return; } @@ -30,40 +95,31 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController", $scope.target = { id: -1, name: "Root" }; } else { - $scope.loading = true; - mediaResource.getById($scope.relation.parentId).then(function (data) { - $scope.loading = false; - $scope.target = data; - // make sure the target item isn't in the recycle bin - if ($scope.target.path.indexOf("-21") !== -1) { - localizationService.localizeMany(["recycleBin_itemCannotBeRestored", "recycleBin_restoreUnderRecycled"]) - .then(function (values) { - $scope.success = false; - $scope.error = { - errorMsg: values[0], - data: { - Message: values[1].replace('%0%', $scope.target.name) - } - } - }); - $scope.success = false; - } + $scope.loading = true; - }, function (err) { - $scope.success = false; - $scope.error = err; + entityResource.getById($scope.relation.parentId, "media").then(function (data) { $scope.loading = false; - }); + $scope.target = data; + + // make sure the target item isn't in the recycle bin + if ($scope.target.path.indexOf("-21") !== -1) { + $scope.moving = true; + $scope.target = null; + } + }, function (err) { + $scope.loading = false; + $scope.error = err; + }); } }, function (err) { - $scope.success = false; - $scope.error = err; $scope.loading = false; + $scope.error = err; }); $scope.restore = function () { - $scope.loading = true; + $scope.loading = true; + // this code was copied from `content.move.controller.js` mediaResource.move({ parentId: $scope.target.id, id: $scope.source.id }) .then(function (path) { @@ -89,9 +145,8 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.RestoreController", }); }, function (err) { - $scope.success = false; - $scope.error = err; $scope.loading = false; + $scope.error = err; }); }; diff --git a/src/Umbraco.Web.UI.Client/src/views/media/restore.html b/src/Umbraco.Web.UI.Client/src/views/media/restore.html index bfc03128a3..6022caa251 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/restore.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/restore.html @@ -1,34 +1,87 @@
    diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js index 4afe62786e..0a44192041 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.controller.js @@ -1,7 +1,7 @@ (function () { "use strict"; - function EditController($scope, $location, $routeParams, umbRequestHelper, entityResource, stylesheetResource, languageResource, packageResource, dictionaryResource, editorService, formHelper) { + function EditController($scope, $location, $routeParams, umbRequestHelper, entityResource, packageResource, editorService, formHelper) { const vm = this; @@ -19,8 +19,8 @@ vm.openContentPicker = openContentPicker; vm.openFilePicker = openFilePicker; vm.removeFile = removeFile; - vm.openControlPicker = openControlPicker; - vm.removeControl = removeControl; + vm.openViewPicker = openViewPicker; + vm.removePackageView = removePackageView; vm.downloadFile = downloadFile; const packageId = $routeParams.id; @@ -73,7 +73,7 @@ }); // get all stylesheets - stylesheetResource.getAll().then(stylesheets => { + entityResource.getAll("Stylesheet").then(stylesheets => { vm.stylesheets = stylesheets; }); @@ -87,7 +87,7 @@ }); // get all languages - languageResource.getAll().then(languages => { + entityResource.getAll("Language").then(languages => { // a package stores the id as a string so we // need to convert all ids to string for comparison languages.forEach(language => { @@ -97,7 +97,7 @@ }); // get all dictionary items - dictionaryResource.getList().then(dictionaryItems => { + entityResource.getAll("DictionaryItem").then(dictionaryItems => { // a package stores the id as a string so we // need to convert all ids to string for comparison dictionaryItems.forEach(dictionaryItem => { @@ -130,7 +130,7 @@ } function back() { - $location.path("packages/packages/overview").search('create', null);; + $location.path("packages/packages/created").search("create", null).search("packageId", null); } function createOrUpdatePackage(editPackageForm) { @@ -148,7 +148,7 @@ if (create) { //if we are creating, then redirect to the correct url and reload - $location.path("packages/packages/edit/" + vm.package.id).search("subview", "created").search("create", null); + $location.path("packages/packages/edit/" + vm.package.id).search("create", null); //don't add a browser history for this $location.replace(); } @@ -220,16 +220,16 @@ vm.package.files.splice(index, 1); } - function openControlPicker() { + function openViewPicker() { const controlPicker = { - title: "Select control", + title: "Select view", section: "settings", treeAlias: "files", entityType: "file", onlyInitialized: false, select: function(node) { const id = unescape(node.id); - vm.package.loadControl = id; + vm.package.packageView = id; editorService.close(); }, close: function() { @@ -239,8 +239,8 @@ editorService.treePicker(controlPicker); } - function removeControl() { - vm.package.loadControl = null; + function removePackageView() { + vm.package.packageView = null; } onInit(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/edit.html b/src/Umbraco.Web.UI.Client/src/views/packages/edit.html index 8ed1a43e8a..5ad5ac2522 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/packages/edit.html @@ -255,23 +255,23 @@ + label="Package options view" + description="Load this view after installation (ex: App_Plugins/MyApp/MyPackageOptions.html). It can be used to configure your package at any time by clicking Options on the installed package listing"> + on-edit="vm.openViewPicker()" + on-remove="vm.removePackageView()"> Add diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/options.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/options.controller.js new file mode 100644 index 0000000000..4fdf6488a0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/packages/options.controller.js @@ -0,0 +1,47 @@ +(function () { + "use strict"; + + function OptionsController($scope, $location, $routeParams, packageResource, umbRequestHelper) { + + const vm = this; + + vm.showBackButton = true; + vm.loading = true; + vm.back = back; + + const packageId = $routeParams.id; + + function onInit() { + + packageResource.getInstalledById(packageId).then(pck => { + vm.package = pck; + + //set the $scope too, packages can then access this if they wanted from their own scope or parent scope + $scope.package = pck; + + vm.loading = false; + + //make sure the packageView is formatted as a virtual path + pck.packageView = pck.packageView.startsWith("/~") + ? pck.packageView + : pck.packageView.startsWith("/") + ? "~" + pck.packageView + : "~/" + pck.packageView; + + pck.packageView = umbRequestHelper.convertVirtualToAbsolutePath(pck.packageView); + + }); + } + + function back() { + $location.path("packages/packages/installed").search("packageId", null); + } + + + onInit(); + + } + + angular.module("umbraco").controller("Umbraco.Editors.Packages.OptionsController", OptionsController); + +})(); diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/options.html b/src/Umbraco.Web.UI.Client/src/views/packages/options.html new file mode 100644 index 0000000000..d75604d094 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/packages/options.html @@ -0,0 +1,40 @@ +
    + + + + + + + + + + + + +

    + This package has no configuration view +

    + +
    + +
    + + + + +
    + + + +
    diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js index ccd86c6f6c..e48271aa23 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/overview.controller.js @@ -1,30 +1,29 @@ (function () { "use strict"; - function PackagesOverviewController($scope, $location, localStorageService) { + function PackagesOverviewController($scope, $location, $routeParams, localStorageService) { //Hack! - // if there is a cookie value for packageInstallUri then we need to redirect there, + // if there is a local storage value for packageInstallData then we need to redirect there, // the issue is that we still have webforms and we cannot go to a hash location and then window.reload // because it will double load it. // we will refresh and then navigate there. - let installPackageUri = localStorageService.get("packageInstallUri"); - let packageUri = $location.search().subview; + let packageInstallData = localStorageService.get("packageInstallData"); + let packageUri = $routeParams.method; - if (installPackageUri) { - localStorageService.remove("packageInstallUri"); + if (packageInstallData) { + localStorageService.remove("packageInstallData"); } - if (installPackageUri && installPackageUri !== "installed") { - //navigate to the custom installer screen, if it is just "installed", then we'll - //show the installed view - $location.path(installPackageUri).search(""); + if (packageInstallData && packageInstallData !== "installed" && packageInstallData.postInstallationPath) { + //navigate to the custom installer screen, if it is just "installed" it means there is no custom installer screen + $location.path(packageInstallData.postInstallationPath).search("packageId", packageInstallData.id); } else { var vm = this; - packageUri = installPackageUri ? installPackageUri : packageUri; //use the path stored in storage over the one in the current path + packageUri = packageInstallData ? packageInstallData : packageUri; //use the path stored in storage over the one in the current path vm.page = {}; vm.page.name = "Packages"; @@ -33,10 +32,10 @@ "name": "Packages", "icon": "icon-cloud", "view": "views/packages/views/repo.html", - "active": !packageUri || packageUri === "navigation", + "active": !packageUri || packageUri === "repo", "alias": "umbPackages", - "action": function() { - $location.search("subview", "navigation"); + "action": function () { + $location.path("/packages/packages/repo"); } }, { @@ -45,8 +44,8 @@ "view": "views/packages/views/installed.html", "active": packageUri === "installed", "alias": "umbInstalled", - "action": function() { - $location.search("subview", "installed"); + "action": function () { + $location.path("/packages/packages/installed"); } }, { @@ -55,8 +54,8 @@ "view": "views/packages/views/install-local.html", "active": packageUri === "local", "alias": "umbInstallLocal", - "action": function() { - $location.search("subview", "local"); + "action": function () { + $location.path("/packages/packages/local"); } }, { @@ -65,8 +64,8 @@ "view": "views/packages/views/created.html", "active": packageUri === "created", "alias": "umbCreatedPackages", - "action": function() { - $location.search("subview", "created"); + "action": function () { + $location.path("/packages/packages/created"); } } ]; diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/install-local.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/views/install-local.controller.js index 17b417de48..0d9341243b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/views/install-local.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/views/install-local.controller.js @@ -184,14 +184,8 @@ installError) .then(function (result) { - if (result.postInstallationPath) { - //Put the redirect Uri in a cookie so we can use after reloading - localStorageService.set("packageInstallUri", result.postInstallationPath); - } - else { - //set to a constant value so it knows to just go to the installed view - localStorageService.set("packageInstallUri", "installed"); - } + //Put the package data in local storage so we can use after reloading + localStorageService.set("packageInstallData", result); vm.installState.status = labels.installStateCompleted; vm.installCompleted = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.controller.js index 5265897708..ddfee19ac1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.controller.js @@ -7,6 +7,7 @@ vm.confirmUninstall = confirmUninstall; vm.uninstallPackage = uninstallPackage; + vm.packageOptions = packageOptions; vm.state = "list"; vm.installState = { status: "" @@ -34,6 +35,11 @@ }); } + function packageOptions(pck) { + $location.path("packages/packages/options/" + pck.id) + .search("packageId", null); //ensure the installId flag is gone, it's only available on first install + } + function confirmUninstall(pck) { vm.state = "packageDetails"; vm.package = pck; @@ -51,7 +57,7 @@ vm.installState.progress = "100"; //set this flag so that on refresh it shows the installed packages list - localStorageService.set("packageInstallUri", "installed"); + localStorageService.set("packageInstallData", "installed"); //reload on next digest (after cookie) $timeout(function () { diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.html b/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.html index 3c443e0bac..888bf02c4e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.html +++ b/src/Umbraco.Web.UI.Client/src/views/packages/views/installed.html @@ -23,12 +23,19 @@ - + + + + diff --git a/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js b/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js index b77326d2fc..dc3e67db15 100644 --- a/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/packages/views/repo.controller.js @@ -257,10 +257,8 @@ error) .then(function (result) { - if (result.postInstallationPath) { - //Put the redirect Uri in a cookie so we can use after reloading - localStorageService.set("packageInstallUri", result.postInstallationPath); - } + //Put the package data in local storage so we can use after reloading + localStorageService.set("packageInstallData", result); vm.installState.status = labels.installStateCompleted; vm.installCompleted = true; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js index c84644d251..1e7e3fa0ed 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js @@ -437,7 +437,7 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs view: "views/propertyeditors/listview/overlays/listviewpublish.html", submitButtonLabelKey: "actions_publish", submit: function (model) { - // create a comma seperated array of selected cultures + // create a comma separated array of selected cultures let selectedCultures = []; if (model.languages && model.languages.length > 0) { model.languages.forEach(language => { @@ -492,7 +492,7 @@ function listViewController($scope, $routeParams, $injector, $timeout, currentUs submitButtonLabelKey: "actions_unpublish", submit: function (model) { - // create a comma seperated array of selected cultures + // create a comma separated array of selected cultures let selectedCultures = []; if (model.languages && model.languages.length > 0) { model.languages.forEach(language => { diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index c21bf7fef6..778ab188cd 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -241,9 +241,6 @@ umbracoSettings.config Designer - - trees.config - tinyMceConfig.config Designer @@ -301,14 +298,6 @@ - - - Designer - - - applications.config - Designer - diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml index f3b16def54..db780bb358 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml @@ -617,14 +617,12 @@ a výběrem balíčku. Balíčky umbraco mají obvykle přípony ".umb" nebo ".zip". ]]> Autor - Ukázka Dokumentace Meta data balíčku Název balíčku Balíček neobsahuje žádné položky
    Můžete jej ze systému bezpečně odstranit kliknutím na "odebrat balíček" níže.]]>
    - Žádné aktualizace nejsou dostupné Možnosti balíčku Čti mě balíčku Úložiště balíčku @@ -635,12 +633,7 @@ Upozornění: všechny dokumenty, media atd. závislé na položkách, které odstraníte, přestanou pracovat a mohou vést k nestabilitě systému, takže odinstalovávejte opatrně. Jste-li na pochybách, kontaktujte autora balíčku.]]> - Stáhnout aktualizaci z úložiště - Balíček s aktualizací - Pokyny pro aktualizaci - Pro tento balíček je dostupná aktualizace. Můžete si ji stáhnout přímo z úložiště balíčků umbraco. Verze balíčku - Zobrazit web balíčku Vložit s úplným formatováním (nedoporučeno) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml index 523531947a..39e1341f37 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/da.xml @@ -840,13 +840,11 @@ Mange hilsner fra Umbraco robotten Denne pakke er kompatibel med de følgende versioner af Umbraco, som rapporteret af community-medlemmer. Fuld kompatibilitet kan ikke garanteres for versioner rapporteret nedenfor 100% Eksterne kilder Forfatter - Demonstration Dokumentation Pakke meta data Pakkenavn Pakken indeholder ingen elementer
    Du kan roligt fjerne denne fra systemet ved at klikke på "Fjern pakke" nedenfor.]]>
    - Ingen opdateringer tilgængelige Pakkevalg Pakke læs mig Pakke opbevaringsbase @@ -856,12 +854,7 @@ Mange hilsner fra Umbraco robotten Afinstallér pakke Bemærk: at dokumenter og medier som afhænger af denne pakke vil muligvis holde op med at virke, så vær forsigtig. Hvis i tvivl, kontakt personen som har udviklet pakken.]]> - Download opdatering fra opbevaringsbasen - Opdatér pakke - Opdateringsinstrukser - Der er en tilgængelig opdatering til denne pakke. Du kan downloade den direkte fra Umbracos pakke opbevaringsbase. Pakke version - Se pakkeudviklerens website Pakke allerede installeret Denne pakke kan ikke installeres, den kræver en minimum Umbraco version af Afinstallerer... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml index 915b25208e..1be81fb10f 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/de.xml @@ -610,13 +610,11 @@ Wenn Sie sich für Runway entscheiden, können Sie optional Blöcke nutzen, die Wählen Sie ein Paket auf Ihrem lokalen Computer über "Datei auswählen" aus. <br />Umbraco-Pakete besitzen üblicherweise die Dateiendungen ".umb" oder ".zip". Autor - Demonstration Dokumentation Paket-Meta-Daten Name des Pakets Paket enthält keine Elemente Die Paket-Datei enthält keine Elemente die deinstalliert werden können.<br/><br/>Sie können das Paket ohne Gefahr deinstallieren indem Sie "Paket deinstallieren" anklicken. - Keine Updates für das Paket verfügbar Paket-Optionen Informationen zum Paket Paket-Repository @@ -625,12 +623,7 @@ Wenn Sie sich für Runway entscheiden, können Sie optional Blöcke nutzen, die Das Paket wurde erfolgreich deinstalliert Paket deinstallieren Sie können einzelne Elemente, die Sie nicht deinstallieren möchten, unten abwählen. Wenn Sie "Deinstallation bestätigen" klicken, werden alle markierten Elemente entfernt.<br /><span style="color: Red; font-weight: bold;">Achtung:</span> alle Dokumente, Medien, etc, die von den zu entfernenden Elementen abhängen, werden nicht mehr funktionieren und im Zweifelsfall kann dass gesamte CMS instabil werden. Bitte deinstallieren Sie also mit Vorsicht. Falls Sie unsicher sind, kontaktieren Sie den Autor des Pakets. - Update vom Paket-Repository herunterladen - Paket-Update - Hinweise für die Durchführung des Updates - Es ist ein Update für dieses Paket verfügbar. Sie können es direkt vom Umbraco-Paket-Repository herunterladen. Version des Pakets - Paket-Webseite aufrufen Einfügen mit Formatierung (Nicht empfohlen) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml index dad27d99fe..d50cac4ac4 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en.xml @@ -1090,14 +1090,12 @@ To manage your website, simply open the Umbraco back office and start adding con This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be gauranteed for versions reported below 100% External sources Author - Demonstration Documentation Package meta data Package name Package doesn't contain any items
    You can safely remove this from the system by clicking "uninstall package" below.]]>
    - No upgrades available Package options Package readme Package repository @@ -1108,12 +1106,7 @@ To manage your website, simply open the Umbraco back office and start adding con Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, so uninstall with caution. If in doubt, contact the package author.]]> - Download update from the repository - Upgrade package - Upgrade instructions - There's an upgrade available for this package. You can download it directly from the Umbraco package repository. Package version - View package website Package already installed This package cannot be installed, it requires a minimum Umbraco version of Uninstalling... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml index ab37cf8025..23efe8047e 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/en_us.xml @@ -1117,14 +1117,12 @@ To manage your website, simply open the Umbraco back office and start adding con This package is compatible with the following versions of Umbraco, as reported by community members. Full compatability cannot be gauranteed for versions reported below 100% External sources Author - Demonstration Documentation Package meta data Package name Package doesn't contain any items
    You can safely remove this from the system by clicking "uninstall package" below.]]>
    - No upgrades available Package options Package readme Package repository @@ -1135,13 +1133,8 @@ To manage your website, simply open the Umbraco back office and start adding con Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, so uninstall with caution. If in doubt, contact the package author.]]> - Download update from the repository - Upgrade package - Upgrade instructions - There's an upgrade available for this package. You can download it directly from the Umbraco package repository. Package version Upgrading from version - View package website Package already installed This package cannot be installed, it requires a minimum Umbraco version of Uninstalling... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml index 7f35e90083..090ecc875e 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/es.xml @@ -863,14 +863,11 @@ Este paquete es compatible con las siguientes versiones de Umbraco, declaradas según miembros de la comunidad. No se puede garantizar compatibilidad completa para versiones declaradas debajo del 100% Fuentes externas Autor - Documentación Meta datos del paquete Nombre del paquete El paquete no contiene ningún elemento
    Puedes eliminarlo del sistema de forma segura seleccionando la opción "desinstalar paquete" de abajo.]]>
    - No hay actualizaciones disponibles Opciones del paquete Léeme del paquete Repositorio de paquetes @@ -879,12 +876,7 @@ El paquete se ha desinstalado correctamente Desinstalar paquete Nota: cualquier documento, archivo etc dependiente de los elementos eliminados, dejará de funcionar, y puede conllevar inestabilidad en el sistema, por lo que lleva cuidado al desinstalar elementos. En caso de duda, contacta con el autor del paquete.]]> - Descargar actualización del repositorio - Actualizar paquete - Instrucciones de actualización - Hay una actualización disponible para este paquete. Puedes descargarla directamente del repositorio de paquetes de Umbraco. Versión del paquete - Ver página web del paquete Paquete ya instalado Este paquete no se puede instalar, requiere un versión mínima de Umbraco de Desinstalando... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml index 04b2cea4df..b6c23d7b63 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/fr.xml @@ -1025,14 +1025,12 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Ce package est compatible avec les versions suivantes de Umbraco, selon les rapports des membres de la communauté. Une compatibilité complète ne peut pas être garantie pour les versions rapportées sous 100% Sources externes Auteur - Démo Documentation Meta data du package Nom du package Le package ne contient aucun élément
    Vous pouvez supprimer tranquillement ce package de votre installation en cliquant sur "Désinstaller le package" ci-dessous.]]>
    - Aucune mise à jour disponible Options du package Package readme Repository des packages @@ -1043,12 +1041,7 @@ Pour gérer votre site, ouvrez simplement le backoffice Umbraco et commencez à Remarque : tous les documents, media etc. dépendant des éléments que vous supprimez vont cesser de fonctionner, ce qui peut provoquer une instabilité du système, désinstallez donc avec prudence. En cas de doute, contactez l'auteur du package.]]> - Télécharger la mise à jour depuis le repository - Mettre à jour le package - Instructions de mise à jour - Il y a une mise à jour disponible pour ce package. Vous pouvez la télécharger directement depuis le repository des packages Umbraco. Version du package - Voir le site internet du package Package déjà installé Ce package ne peut pas être installé, il nécessite au minimum la version Umbraco %0% Désinstallation... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml index 011745ac0f..8d3822943a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/he.xml @@ -548,14 +548,12 @@ To manage your website, simply open the Umbraco back office and start adding con ויש לבחור את החבילה הרצויה. לחבילות Umbraco יש בד"כ יש סיומות בשם ".umb" או ".zip". ]]> יוצר החבילה - הדגמה תיעוד מטה דטה עבור החבילה שם החבילה החבילה לא מכילה אף פריט
    ניתן למחוק בבטיחות רבה את החבילה מהמערכת על ידי לחיצה על "הסר חבילה".]]>
    - אין עידכונים זמינים אפשרויות חבילה תיאור החבילה מאגר חבילות @@ -566,12 +564,7 @@ To manage your website, simply open the Umbraco back office and start adding con הערה:כל מסמך, מדיה וכו' התלוים בפריטים שהסרת יפסיקו לעבוד, ויכולים להביא למצב של אי יציבות למערכת, יש למחוק קבצים עם זהירות יתרה, אם יש ספק יש לפנות ליוצר החבילה.]]> - הורד עידכון מהמאגר - שידרוג חבילה - הורדות שידרוג - קיים עידכון זמין עבור חבילה זו. ניתן להוריד אותו ישירות ממאגר החבילות של אומברקו. גירסת החבילה - צפה באתר החבילה שמור עיצוב בהדבקה (לא מומלץ) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml index a55c626625..6796fdfc3c 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/it.xml @@ -524,14 +524,12 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i e selezionando il pacchetto. I pacchetti Umbraco generalmente hanno l'estensione ".umb" o ".zip". ]]> Autore - Dimostrazione Documentazione Meta dati pacchetto Nome del pacchetto Il pacchetto non contiene tutti gli elementi
    E' possibile rimuovere questo pacchetto dal sistema cliccando "rimuovi pacchetto" in basso.]]>
    - Non ci sono aggiornamenti disponibili Opzioni pacchetto Pacchetto leggimi Pacchetto repository @@ -542,12 +540,7 @@ Per gestire il tuo sito web, è sufficiente aprire il back office di Umbraco e i Avviso: tutti i documenti, i media, etc a seconda degli elementi che rimuoverai, smetteranno di funzionare, e potrebbero portare a un'instabilità del sistema, perciò disinstalla con cautela. In caso di dubbio contattare l'autore del pacchetto.]]> - - Aggiorna pacchetto - - Versione del pacchetto - Vedi sito web pacchetto diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml index 993a99ceec..ae30fde3c4 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ja.xml @@ -692,14 +692,12 @@ Runwayをインストールして作られた新しいウェブサイトがど パッケージを選択できます。Umbracoのパッケージは概ね".zip"ないしは".umb"といった拡張子です。 ]]> 作成者 - デモ ヘルプ パッケージのメタデータ パッケージ名 パッケージには何も含まれません
    "パッケージのアンインストール"をクリックしてシステムから安全に削除できます。]]>
    - 更新はありません パッケージのオプション パッケージの取扱説明書 パッケージリポジトリ @@ -710,12 +708,7 @@ Runwayをインストールして作られた新しいウェブサイトがど 注意: 全ての、文書やメディアなどに依存したアイテムを削除する場合はそれらの作業を一端止めてからアンインストールしなければシステムが不安定になる恐れがあります。 疑問点などあればパッケージの作者へ連絡してください。]]> - リポジトリからアップデートをダウンロード - パッケージのアップグレード - 更新の手順 - このパッケージの更新があります。Umbracoのパッケージリポジトリから直接ダウンロードできます。 パッケージのバージョン - パッケージのウェブサイトを見る 完全な書式を含んだまま貼り付け (非推奨) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml index 7a46ea81c8..7507ca07e8 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ko.xml @@ -532,14 +532,12 @@ Umbraco 패키지는 보통 ".umb" 나 ".zip" 확장자를 가집니다. ]]> 저자 - 데모 문서화 패키지 메타데이터 패키지 이름 패키지가 포함한 아이템이 없습니다.
    아래 "패키지 삭제"를 클릭하시면 안전하게 시스템에서 삭제하실 수 있습니다.]]>
    - 업그레이드할 패키지가 없습니다. 패키지 옵션 패키지 정보 패키지 저장소 @@ -550,12 +548,7 @@ 알림: 문서, 미디어등 삭제항목에 관련된 모든 항목이 삭제됩니다, 작업을 중단하면 시스템이 불안정적으로 동작할 수 있습니다. 삭제는 매우 주의를 요하기 때문에 의심스러운항목은 패키지 제작자에게 문의하시기 바랍니다.]]> - 저장소에서 업데이트 다운로드 - 업그레이드 패키지 - 업그레이드 지시사항 - 업그레이드할 패키지가 없습니다. Umbraco패키지 저장소에서 직접다운로드하실 수 있습니다. 패키지 버전 - 패키지 웹사이트 보기 포맷을 포함여하 붙여넣기(권장하지 않음) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml index a3c8abb946..39f4dd9560 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/nb.xml @@ -589,13 +589,11 @@ Vennlig hilsen Umbraco roboten Umbraco-pakker har vanligvis endelsen ".umb" eller ".zip".]]> Utvikler - Demonstrasjon Dokumentasjon Metadata Pakkenavn Pakken inneholder ingen elementer
    Du kan trygt fjerne pakken fra systemet ved å klikke "avinstaller pakke" nedenfor.]]>
    - Ingen oppdateringer tilgjengelig Alternativer for pakke Lesmeg for pakke Pakkebrønn @@ -604,12 +602,7 @@ Vennlig hilsen Umbraco roboten Pakken ble vellykket avinstallert Avinstaller pakke Advarsel: alle dokumenter, media, etc. som som er avhengig av elementene du sletter, vil slutte å virke, noe som kan føre til ustabilitet, så avinstaller med forsiktighet. Hvis du er i tvil, kontakt pakkeutvikleren.]]> - Last ned oppdatering fra pakkeregisteret - Oppgrader pakke - Oppgraderingsinstrukser - Det er en oppdatering tilgjengelig for denne pakken. Du kan laste den ned direkte fra pakkebrønnen. Pakkeversjon - Se pakkens nettsted Lim inn med full formattering (Anbefales ikke) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml index 8189be9429..4722abb557 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/nl.xml @@ -698,7 +698,6 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Kies een package op je computer door op "Bladeren" te klikken en de package te selecteren. Umbraco packages hebben meestal ".umb" of ".zip" als extensie. Auteur - Demonstratie Documentatie Package meta data Package naam @@ -706,7 +705,6 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je
    Je kunt deze package veilig verwijderen door op 'verwijder package' te klikken. ]]>
    - Geen upgrades beschikbaar Package opties Package lees mij Package repository @@ -718,12 +716,7 @@ Echter, Runway biedt een gemakkelijke basis om je snel op weg te helpen. Als je Waarschuwing: alle documenten, media etc, die afhankelijk zijn van de items die je verwijderd, zullen niet meer werken en kan leiden tot een instabiele installatie, wees dus voorzichtig met verwijderen. Als je het niet zeker weet, neem dan contact op met de auteur van de package. ]]> - Download update uit de repository - Upgrade package - Upgrade instructies - Er is een upgrade beschikbaar voor deze package. Je kunt het direct downloaden uit de Umbraco package repository. Package versie - Bekijk de package website Package reeds geinstalleerd Deze package kan niet worden geinstalleerd omdat minimaal Umbraco versie %0% benodigd is. Aan het deinstalleren... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml index 1f64a5ab21..788afd3c1a 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/pl.xml @@ -859,14 +859,12 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Według raportów członków społeczności, ten pakiet jest zgodny z następującymi wersjami Umbraco. Pełna zgodność nie może być zagwarantowana dla wersji zaraportowanych poniżej 100% Zewnętrzne źródła Autor - Demonstracja Dokumentacja Metadane pakietu Nazwa pakietu Pakiet nie zawiera żadnych elementów
    Możesz bezpiecznie go usunąć z systemu poprzez kliknięcie na przycisku "odinstaluj pakiet"]]>
    - Nie ma dostępnych aktualizacji Opcje pakietu Opis pakietu Repozytorium pakietu @@ -877,12 +875,7 @@ Naciśnij przycisk instaluj, aby zainstalować bazę danych Umb Uwaga: wszystkie elementy, media, itp. w zależności od elementów, które usuwasz, przestaną działać i mogą spowodować niestabilność systemu, więc odinstalowuj z uwagą. W przypadku problemów skontaktuj się z autorem pakietu.]]> - Pobierz aktualizację z repozytorium - Aktualizuj pakiet - Instrukcja aktualizacji - Jest dostępna aktualizacja dla tego pakietu. Możesz ją pobrać wprost z repozytorium pakietów Umbraco. Wersja pakietu - Odwiedź stronę pakietu Pakiet jest już zainstalowany Ten pakiet nie może być zainstalowany, ponieważ wymaga Umbraco w wersji przynajmniej %0% Odinstalowywanie... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml index cff6009bb4..56297d23df 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/pt.xml @@ -522,14 +522,12 @@ Vá até http://%4%/#/content/content/edit/%5% para editar. e localizando o pacote. Pacotes Umbraco tem extensão ".umb" ou ".zip".]]> Autor - Demonstração Documentação Dado meta do pacote Nome do pacote Pacote não contém nenhum item
    Você pode remover com segurança do seu sistema clicando em "desinstalar pacote" abaixo.]]>
    - Nenhuma atualização disponível Oções do pacote Leia-me do pacote Repositório do pacote @@ -539,12 +537,7 @@ Você pode remover com segurança do seu sistema clicando em "desinstalar pacote Desinstalar pacote Aviso: quaisquer documentos, mídia, etc dependentes dos itens que forem removidos vão parar de funcionar e podem levar à instabilidade do sistema. Então desinstale com cuidado. Se tiver dúvidas, contate o autor do pacote]]> - Baixar atualização pelo repositório - Atualizar pacote - Instruções de atualização - Há uma atualizaçào disponível para este pacote. Você pode baixá-lo diretamente do repositório de pacotes do Umbraco. Versão do pacote - Ver website do pacote Colar com formatação completa (Não recomendado) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml index 61c42d9d6d..1744d19581 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/ru.xml @@ -1182,14 +1182,12 @@ Этот пакет совместим со следующими версиями Umbraco, по сообщениям участников сообщества. Полная совместимость не гарантируется для версий со значением ниже 100% Внешние источники Автор - Демонстрация Документация (описание) Мета-данные пакета Название пакета Пакет ничего не содержит
    Вы можете безопасно удалить данный пакет из системы, нажав на кнопку "Деинсталлировать пакет".]]>
    - Нет доступных обновлений Опции пакета Краткий обзор пакета Репозиторий пакета @@ -1200,12 +1198,7 @@ Обратите внимание: все документы, медиа-файлы и другой контент, зависящий от этого пакета, перестанет нормально работать, что может привести к нестабильному поведению системы, поэтому удаляйте пакеты очень осторожно. При наличии сомнений, свяжитесь с автором пакета.]]> - Скачать обновление из репозитория - Обновление пакета - Руководство по обновлению - Для данного пакета доступно обновление. Вы можете загрузить это обновление непосредственно из центрального репозитория пакетов Umbraco. Версия пакета - Перейти на веб-сайт пакета Этот пакет уже установлен в системе Этот пакет не может быть установлен, он требует наличия Umbraco версии как минимум Удаление... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml index 05c6dc927d..625caa0432 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/sv.xml @@ -544,13 +544,11 @@ och leta upp paketet. Umbracos installationspaket har oftast filändelsen ".umb" eller ".zip".]]> Utvecklare - Demonstration Dokumentation Paket metadata Paketnamn Paketet innehåller inga poster
    Det är säkert att ta bort den ur systemet genom att klicka på "avinstallera paket" nedan.]]>
    - Inga uppdateringar tillgängliga Paketalternativ Paket läsmig Paketvalv @@ -559,12 +557,7 @@ Paketet har avinstallerats utan problem Avinstallera paket OBS! dokument, media osv som använder de borttagna posterna kommer sluta fungera vilket kan leda till att systemet blir instabilt. Avinstallera därför med försiktighet. Om du är osäker, kontakta personen som skapat paketet.]]> - Hämta uppdatering från paketvalvet - Uppdatera paket - Uppdateringsinstruktioner - Det finns an uppdaterad version av paketet. Du kan hämta den direkt från Umbracos paketvalv. Paketversion - Besök paketets webbplats Klistra in med helt bibehållen formatering (rekommenderas ej) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml index 4ff9d22c86..053430d68d 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/tr.xml @@ -609,14 +609,12 @@ To manage your website, simply open the Umbraco back office and start adding con button and locating the package. Umbraco packages usually have a ".umb" or ".zip" extension. ]]> Author - Demonstration Documentation Package meta data Package name Package doesn't contain any items
    You can safely remove this from the system by clicking "uninstall package" below.]]>
    - No upgrades available Package options Package readme Package repository @@ -627,12 +625,7 @@ To manage your website, simply open the Umbraco back office and start adding con Notice: any documents, media etc depending on the items you remove, will stop working, and could lead to system instability, so uninstall with caution. If in doubt, contact the package author.]]> - Download update from the repository - Upgrade package - Upgrade instructions - There's an upgrade available for this package. You can download it directly from the Umbraco package repository. Package version - View package website Paste with full formatting (Not recommended) diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml index 7286c3f914..227e40cf94 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/zh.xml @@ -728,14 +728,12 @@ 选择 ".umb" 或者 ".zip" 文件 ]]> 作者 - 演示 文档 元数据 名称 扩展包不含任何项
    点击下面的“卸载”,您可以安全的删除。]]>
    - 无可用更新 选项 说明 程序库 @@ -746,12 +744,7 @@ 注意: 卸载包将导致所有依赖该包的东西失效,请确认。 ]]> - 从程序库下载更新 - 更新扩展包 - 更新说明 - 此软件包有一个可用的升级。您可以直接从 Umbraco 软件包存储库下载。 版本 - 访问扩展包网站 已安装软件包 此软件包无法安装, 它需要一个最小的 Umbraco 版本的%0% 卸载中... diff --git a/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml b/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml index b61e1154b8..23da0c817c 100644 --- a/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml +++ b/src/Umbraco.Web.UI/Umbraco/config/lang/zh_tw.xml @@ -714,14 +714,12 @@ 按鈕並點選該檔案。Umbraco擴展包通常有「.zip」的副檔名。 ]]> 作者 - 演示 文檔 中繼資料 名稱 擴展包不含任何項
    您可以點選下方「移除擴展包」來安全地移除此項目。]]>
    - 無可用更新 選項 說明 程式庫 @@ -732,12 +730,7 @@ 注意: 任何文檔,媒體或需要這些項目才能運作的物件將會停止運作,並可能使得系統不穩定, 請小心移除。若有疑慮,請聯絡擴展包作者。]]> - 從程式庫下載更新 - 更新擴展包 - 更新說明 - 擴展包有可用的更新,您可以從程式庫網站更新。 版本 - 訪問擴展包網站 擴展包已安裝 這個擴展包無法安裝,它需要Umbraco至少是版本 %0% 移除中... diff --git a/src/Umbraco.Web.UI/config/applications.Release.config b/src/Umbraco.Web.UI/config/applications.Release.config deleted file mode 100644 index 5c8dee3b8a..0000000000 --- a/src/Umbraco.Web.UI/config/applications.Release.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/config/applications.config b/src/Umbraco.Web.UI/config/applications.config deleted file mode 100644 index 5c8dee3b8a..0000000000 --- a/src/Umbraco.Web.UI/config/applications.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/config/trees.Release.config b/src/Umbraco.Web.UI/config/trees.Release.config deleted file mode 100644 index bd75e97c38..0000000000 --- a/src/Umbraco.Web.UI/config/trees.Release.config +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/config/trees.config b/src/Umbraco.Web.UI/config/trees.config deleted file mode 100644 index 5892545682..0000000000 --- a/src/Umbraco.Web.UI/config/trees.config +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index fb8ff63ab0..7299a397bc 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config @@ -85,11 +85,6 @@ - - - Mvc - - diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index c3e146d6ce..4de0a04735 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -162,11 +162,6 @@ - - - Mvc - -