From 74e1078c31baddf6cdff8bdb668c97ae95b36376 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 30 Mar 2016 16:07:45 +0200 Subject: [PATCH] Merge branch 'U4-8198_file_system' of https://github.com/yannisgu/Umbraco-CMS into yannisgu-U4-8198_file_system Conflicts: src/Umbraco.Web/Umbraco.Web.csproj --- src/Umbraco.Core/Constants-Applications.cs | 8 +- .../lib/umbraco/LegacyUmbClientMgr.js | 3 + .../config/trees.Release.config | 25 +-- src/Umbraco.Web.UI/config/trees.config | 11 +- .../umbraco/config/create/UI.xml | 23 +++ .../umbraco/settings/views/EditView.aspx.cs | 6 +- src/Umbraco.Web/Models/Trees/MenuItem.cs | 20 ++- .../Trees/FileSystemTreeController.cs | 163 +++++++++++++----- .../Trees/PartialViewMacrosTree.cs | 48 ------ .../Trees/PartialViewMacrosTreeController.cs | 24 +++ src/Umbraco.Web/Trees/PartialViewsTree.cs | 87 ---------- .../Trees/PartialViewsTreeController.cs | 49 ++++++ .../Trees/ScriptsTreeController.cs | 48 ++++++ .../Trees/StylesheetsTreeController.cs | 107 ++++++++++++ src/Umbraco.Web/Trees/XsltTreeController.cs | 41 +++++ src/Umbraco.Web/Umbraco.Web.csproj | 16 +- .../umbraco/Trees/FileSystemTree.cs | 134 -------------- .../umbraco/Trees/loadScripts.cs | 92 ---------- .../umbraco/Trees/loadStylesheetProperty.cs | 64 ------- .../umbraco/Trees/loadStylesheets.cs | 74 -------- .../umbraco/Trees/loadXslt.cs | 66 ------- .../umbraco/developer/Xslt/editXslt.aspx.cs | 2 +- .../settings/scripts/editScript.aspx.cs | 2 +- .../stylesheet/editstylesheet.aspx.cs | 2 +- .../property/EditStyleSheetProperty.aspx.cs | 8 +- 25 files changed, 476 insertions(+), 647 deletions(-) delete mode 100644 src/Umbraco.Web/Trees/PartialViewMacrosTree.cs create mode 100644 src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs delete mode 100644 src/Umbraco.Web/Trees/PartialViewsTree.cs create mode 100644 src/Umbraco.Web/Trees/PartialViewsTreeController.cs create mode 100644 src/Umbraco.Web/Trees/ScriptsTreeController.cs create mode 100644 src/Umbraco.Web/Trees/StylesheetsTreeController.cs create mode 100644 src/Umbraco.Web/Trees/XsltTreeController.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/Trees/FileSystemTree.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadScripts.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheetProperty.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheets.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadXslt.cs diff --git a/src/Umbraco.Core/Constants-Applications.cs b/src/Umbraco.Core/Constants-Applications.cs index 1c15083a81..5fb2fd7d8a 100644 --- a/src/Umbraco.Core/Constants-Applications.cs +++ b/src/Umbraco.Core/Constants-Applications.cs @@ -114,7 +114,13 @@ /// public const string UserTypes = "userTypes"; - //TODO: Fill in the rest! + public const string Scripts = "scripts"; + + public const string PartialViews = "partialViews"; + + public const string PartialViewMacros = "partialViewMacros"; + + //TODO: Fill in the rest! } } diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js index 06d6c11c71..51d437b9cb 100644 --- a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js +++ b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js @@ -106,6 +106,9 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); treeService.clearCache(); }); }, + childNodeCreated: function() { + //no-op, just needs to be here for legacy reasons + }, reloadActionNode: function () { angularHelper.safeApply($rootScope, function() { var currentMenuNode = appState.getMenuState("currentNode"); diff --git a/src/Umbraco.Web.UI/config/trees.Release.config b/src/Umbraco.Web.UI/config/trees.Release.config index bdf30ed8f3..91efd6bc8b 100644 --- a/src/Umbraco.Web.UI/config/trees.Release.config +++ b/src/Umbraco.Web.UI/config/trees.Release.config @@ -3,47 +3,38 @@ - - - - - - - + + + + - - - - + + - + - - - + - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI/config/trees.config b/src/Umbraco.Web.UI/config/trees.config index 364ecfd4fd..1bad226db8 100644 --- a/src/Umbraco.Web.UI/config/trees.config +++ b/src/Umbraco.Web.UI/config/trees.config @@ -9,10 +9,9 @@ - - - - + + + @@ -21,8 +20,8 @@ - - + + diff --git a/src/Umbraco.Web.UI/umbraco/config/create/UI.xml b/src/Umbraco.Web.UI/umbraco/config/create/UI.xml index f6859c6423..da74f6527b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/create/UI.xml +++ b/src/Umbraco.Web.UI/umbraco/config/create/UI.xml @@ -40,6 +40,7 @@
Xslt
/create/xslt.ascx + @@ -72,6 +73,14 @@ + +
Stylesheet
+ /create/simple.ascx + + + + +
XSLT file
/create/xslt.ascx @@ -229,6 +238,13 @@
+ +
Macro
+ /Create/PartialView.ascx + + + +
Macro
/Create/PartialViewMacro.ascx @@ -237,6 +253,13 @@
+ +
Macro
+ /Create/PartialViewMacro.ascx + + + +
Macro
/Create/PartialView.ascx diff --git a/src/Umbraco.Web.UI/umbraco/settings/views/EditView.aspx.cs b/src/Umbraco.Web.UI/umbraco/settings/views/EditView.aspx.cs index 58c78827ec..a91414fd02 100644 --- a/src/Umbraco.Web.UI/umbraco/settings/views/EditView.aspx.cs +++ b/src/Umbraco.Web.UI/umbraco/settings/views/EditView.aspx.cs @@ -64,9 +64,9 @@ namespace Umbraco.Web.UI.Umbraco.Settings.Views get { if (Request.QueryString["treeType"].IsNullOrWhiteSpace()) - { - return TreeDefinitionCollection.Instance.FindTree().Tree.Alias; - } + { + return Constants.Trees.PartialViews; + } return Request.CleanForXss("treeType"); } } diff --git a/src/Umbraco.Web/Models/Trees/MenuItem.cs b/src/Umbraco.Web/Models/Trees/MenuItem.cs index 8e0f581e78..e1a656857a 100644 --- a/src/Umbraco.Web/Models/Trees/MenuItem.cs +++ b/src/Umbraco.Web/Models/Trees/MenuItem.cs @@ -191,7 +191,25 @@ namespace Umbraco.Web.Models.Trees view => LaunchDialogView( view, ApplicationContext.Current.Services.TextService.Localize("defaultdialogs/confirmdelete") + " '" + (item == null ? "" : item.Name) + "' ?")); - } + } + + internal void ConvertLegacyFileSystemMenuItem(string path, string nodeType, string currentSection) + { + //First try to get a URL/title from the legacy action, + // if that doesn't work, try to get the legacy confirm view + + //in some edge cases, item can be null so we'll just convert those to "-1" and "" for id and name since these edge cases don't need that. + Attempt + .Try(LegacyTreeDataConverter.GetUrlAndTitleFromLegacyAction(Action, + path, + nodeType, + path, currentSection), + action => LaunchDialogUrl(action.Url, action.DialogTitle)) + .OnFailure(() => LegacyTreeDataConverter.GetLegacyConfirmView(Action, currentSection), + view => LaunchDialogView( + view, + ApplicationContext.Current.Services.TextService.Localize("defaultdialogs/confirmdelete") + " '" + path + "' ?")); + } #endregion } diff --git a/src/Umbraco.Web/Trees/FileSystemTreeController.cs b/src/Umbraco.Web/Trees/FileSystemTreeController.cs index f9ebaaf2d6..3c612281f5 100644 --- a/src/Umbraco.Web/Trees/FileSystemTreeController.cs +++ b/src/Umbraco.Web/Trees/FileSystemTreeController.cs @@ -2,35 +2,50 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Net.Http.Formatting; using System.Text; using System.Threading.Tasks; +using ClientDependency.Core; +using Umbraco.Core; using Umbraco.Core.IO; +using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Models.Trees; +using Umbraco.Web._Legacy.Actions; +using Constants = Umbraco.Core.Constants; namespace Umbraco.Web.Trees { public abstract class FileSystemTreeController : TreeController { protected abstract string FilePath { get; } - protected abstract string FileSearchPattern { get; } + protected abstract IEnumerable FileSearchPattern { get; } + protected abstract string EditFormUrl { get; } + protected abstract bool EnableCreateOnFolder { get; } /// /// Inheritors can override this method to modify the file node that is created. /// /// - protected virtual void OnRenderFileNode(ref TreeNode treeNode) { } + protected virtual void OnRenderFileNode(TreeNode treeNode, FileInfo file) + { + } /// /// Inheritors can override this method to modify the folder node that is created. /// /// - protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { } - - protected override Models.Trees.TreeNodeCollection GetTreeNodes(string id, System.Net.Http.Formatting.FormDataCollection queryStrings) + protected virtual void OnRenderFolderNode(TreeNode treeNode) { + } + + protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) + { + var nodes = new TreeNodeCollection(); + string orgPath = ""; string path = ""; - if (!string.IsNullOrEmpty(id) && id != "-1") + if (!string.IsNullOrEmpty(id) && id != Constants.System.Root.ToInvariantString()) { orgPath = id; path = IOHelper.MapPath(FilePath + "/" + orgPath); @@ -41,54 +56,124 @@ namespace Umbraco.Web.Trees path = IOHelper.MapPath(FilePath); } - DirectoryInfo dirInfo = new DirectoryInfo(path); - DirectoryInfo[] dirInfos = dirInfo.GetDirectories(); + if (!Directory.Exists(path) && !System.IO.File.Exists(path)) + { + return nodes; + } + + if (System.IO.File.Exists(path)) + { + return GetTreeNodesForFile(path, id, queryStrings); + } + + DirectoryInfo dirInfo = new DirectoryInfo(path); + DirectoryInfo[] dirInfos = new DirectoryInfo(path).GetDirectories(); - var nodes = new TreeNodeCollection(); foreach (DirectoryInfo dir in dirInfos) { - if ((dir.Attributes & FileAttributes.Hidden) == 0) + if ((dir.Attributes.HasFlag(FileAttributes.Hidden)) == false) { - var HasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0; - var node = CreateTreeNode(orgPath + dir.Name, orgPath, queryStrings, dir.Name, "icon-folder", HasChildren); + var hasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0; + var node = CreateTreeNode(orgPath + dir.Name, orgPath, queryStrings, dir.Name, "icon-folder", + hasChildren); - OnRenderFolderNode(ref node); - if(node != null) - nodes.Add(node); + //TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now. + node.AdditionalData["jsClickCallback"] = "javascript:void(0);"; + OnRenderFolderNode(node); + + nodes.Add(node); } } - //this is a hack to enable file system tree to support multiple file extension look-up - //so the pattern both support *.* *.xml and xml,js,vb for lookups - string[] allowedExtensions = new string[0]; - bool filterByMultipleExtensions = FileSearchPattern.Contains(","); - FileInfo[] fileInfo; + var files = FileSearchPattern + .SelectMany(p => dirInfo.GetFiles("*." + p)) + .Where(f => !f.Attributes.HasFlag(FileAttributes.Hidden)); - if (filterByMultipleExtensions) + foreach (FileInfo file in files) { - fileInfo = dirInfo.GetFiles(); - allowedExtensions = FileSearchPattern.ToLower().Split(','); - } - else - fileInfo = dirInfo.GetFiles(FileSearchPattern); + var nodeId = orgPath + file.Name; - foreach (FileInfo file in fileInfo) - { - if ((file.Attributes & FileAttributes.Hidden) == 0) - { - if (filterByMultipleExtensions && Array.IndexOf(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0) - continue; + var node = CreateTreeNode( + nodeId, + orgPath, queryStrings, + file.Name.StripFileExtension(), + "icon-file", + false, + "/" + queryStrings.GetValue("application") + "/framed/" + + Uri.EscapeDataString(string.Format(EditFormUrl, nodeId))); - var node = CreateTreeNode(orgPath + file.Name, orgPath, queryStrings, file.Name, "icon-file", false); + OnRenderFileNode(node, file); - OnRenderFileNode(ref node); - - if(node != null) - nodes.Add(node); - } + nodes.Add(node); } return nodes; - } + } + + protected virtual TreeNodeCollection GetTreeNodesForFile(string path, string id, FormDataCollection queryStrings) + { + return new TreeNodeCollection(); + } + + + protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings) + { + + var menu = new MenuItemCollection(); + + OnBeforeRenderMenu(menu, id, queryStrings); + + if (id == Constants.System.Root.ToInvariantString()) + { + //Create the normal create action + menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)) + //Since we haven't implemented anything for file systems in angular, this needs to be converted to + //use the legacy format + .ConvertLegacyFileSystemMenuItem("", "init" + TreeAlias, queryStrings.GetValue("application")); + + //refresh action + menu.Items.Add( + Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + + return menu; + + } + + if (Directory.Exists(IOHelper.MapPath(FilePath + "/" + id))) + { + if (EnableCreateOnFolder) + { + //Create the normal create action + menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)) + //Since we haven't implemented anything for file systems in angular, this needs to be converted to + //use the legacy format + .ConvertLegacyFileSystemMenuItem(id, TreeAlias + "Folder", + queryStrings.GetValue("application")); + } + + //refresh action + menu.Items.Add( + Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + + } + + //add delete option for all languages + menu.Items.Add(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true) + .ConvertLegacyFileSystemMenuItem( + id, TreeAlias, queryStrings.GetValue("application")); + + OnAfterRenderMenu(menu, id, queryStrings); + + return menu; + } + + protected virtual void OnBeforeRenderMenu(MenuItemCollection menu, string id, FormDataCollection queryStrings) + { + } + + protected virtual void OnAfterRenderMenu(MenuItemCollection menu, string id, FormDataCollection queryStrings) + { + + } } } diff --git a/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs b/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs deleted file mode 100644 index fdde9beb4c..0000000000 --- a/src/Umbraco.Web/Trees/PartialViewMacrosTree.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System.Text; -using Umbraco.Core.IO; -using umbraco.cms.presentation.Trees; -using Umbraco.Core; - -namespace Umbraco.Web.Trees -{ - /// - /// Tree for displaying partial view macros in the developer app - /// - [Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)] - public class PartialViewMacrosTree : PartialViewsTree - { - public PartialViewMacrosTree(string application) : base(application) - { - } - - protected override string FilePath - { - get { return SystemDirectories.MvcViews + "/MacroPartials/"; } - } - - public override void RenderJS(ref StringBuilder javascript) - { - javascript.Append( - @" - function openMacroPartialView(id) { - UmbClientMgr.contentFrame('Settings/Views/EditView.aspx?treeType=partialViewMacros&file=' + id); - } - "); - - }/// - /// Ensures that no folders can be added - /// - /// - protected override void OnRenderFolderNode(ref XmlTreeNode xNode) - { - base.OnRenderFolderNode(ref xNode); - - xNode.NodeType = "partialViewMacrosFolder"; - } - - protected override void ChangeNodeAction(XmlTreeNode xNode) - { - xNode.Action = xNode.Action.Replace("openFile", "openMacroPartialView"); - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs b/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs new file mode 100644 index 0000000000..d4213c7996 --- /dev/null +++ b/src/Umbraco.Web/Trees/PartialViewMacrosTreeController.cs @@ -0,0 +1,24 @@ +using System.Text; +using Umbraco.Core.IO; +using umbraco.cms.presentation.Trees; +using Umbraco.Core; + +namespace Umbraco.Web.Trees +{ + /// + /// Tree for displaying partial view macros in the developer app + /// + [Tree(Constants.Applications.Developer, Constants.Trees.PartialViewMacros, "Partial View Macro Files", sortOrder: 6)] + public class PartialViewMacrosTreeController : PartialViewsTreeController + { + protected override string FilePath + { + get { return SystemDirectories.MvcViews + "/MacroPartials/"; } + } + + protected override string EditFormUrl + { + get { return "Settings/Views/EditView.aspx?treeType=partialViewMacros&file={0}"; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/PartialViewsTree.cs b/src/Umbraco.Web/Trees/PartialViewsTree.cs deleted file mode 100644 index ff7edd8fb7..0000000000 --- a/src/Umbraco.Web/Trees/PartialViewsTree.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Web; -using Umbraco.Core; -using Umbraco.Core.Configuration; -using Umbraco.Core.IO; - -using umbraco.cms.businesslogic.template; -using umbraco.cms.presentation.Trees; -using Umbraco.Web._Legacy.Actions; - -namespace Umbraco.Web.Trees -{ - /// - /// Tree for displaying partial views in the settings app - /// - [Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)] - public class PartialViewsTree : FileSystemTree - { - public PartialViewsTree(string application) : base(application) { } - - public override void RenderJS(ref StringBuilder javascript) - { - javascript.Append( - @" - function openPartialView(id) { - UmbClientMgr.contentFrame('Settings/Views/EditView.aspx?treeType=partialViews&file=' + id); - } - "); - } - - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - rootNode.NodeType = TreeAlias; - rootNode.NodeID = "init"; - } - - protected override string FilePath - { - get { return SystemDirectories.MvcViews + "/Partials/"; } - } - - protected override string FileSearchPattern - { - get { return "*.cshtml"; } - } - - /// - /// Ensures that no folders can be added - /// - /// - protected override void OnRenderFolderNode(ref XmlTreeNode xNode) - { - // We should allow folder hierarchy for organization in large sites. - xNode.Action = "javascript:void(0);"; - xNode.NodeType = "partialViewsFolder"; - xNode.Menu = new List(new IAction[] - { - ActionNew.Instance, - ContextMenuSeperator.Instance, - ActionDelete.Instance, - ContextMenuSeperator.Instance, - ActionRefresh.Instance - }); - - } - - protected virtual void ChangeNodeAction(XmlTreeNode xNode) - { - xNode.Action = xNode.Action.Replace("openFile", "openPartialView"); - } - - protected override void OnRenderFileNode(ref XmlTreeNode xNode) - { - ChangeNodeAction(xNode); - xNode.Icon = "icon-article"; - xNode.OpenIcon = "icon-article"; - - xNode.Text = xNode.Text.StripFileExtension(); - } - - - } -} diff --git a/src/Umbraco.Web/Trees/PartialViewsTreeController.cs b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs new file mode 100644 index 0000000000..3255c87e40 --- /dev/null +++ b/src/Umbraco.Web/Trees/PartialViewsTreeController.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Web; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; + +using umbraco.cms.businesslogic.template; +using umbraco.cms.presentation.Trees; +using Umbraco.Web.Models.Trees; +using Umbraco.Web._Legacy.Actions; + +namespace Umbraco.Web.Trees +{ + /// + /// Tree for displaying partial views in the settings app + /// + [Tree(Constants.Applications.Settings, Constants.Trees.PartialViews, "Partial Views", sortOrder: 2)] + public class PartialViewsTreeController : FileSystemTreeController + { + protected override string FilePath + { + get { return SystemDirectories.MvcViews + "/Partials/"; } + } + + protected override IEnumerable FileSearchPattern + { + get { return new[] {"cshtml"}; } + } + + protected override string EditFormUrl + { + get { return "Settings/Views/EditView.aspx?treeType=partialViews&file={0}"; } + } + + protected override bool EnableCreateOnFolder + { + get { return true; } + } + + protected override void OnRenderFileNode(TreeNode treeNode, FileInfo file) + { + treeNode.Icon = "icon-article"; + } + } +} diff --git a/src/Umbraco.Web/Trees/ScriptsTreeController.cs b/src/Umbraco.Web/Trees/ScriptsTreeController.cs new file mode 100644 index 0000000000..7409230d24 --- /dev/null +++ b/src/Umbraco.Web/Trees/ScriptsTreeController.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http.Formatting; +using Umbraco.Core; +using Umbraco.Core.Configuration; +using Umbraco.Core.IO; +using Umbraco.Web.Models.Trees; + +namespace Umbraco.Web.Trees +{ + [Tree(Constants.Applications.Settings, Constants.Trees.Scripts, "Scripts", "icon-folder", "icon-folder", sortOrder: 2)] + public class ScriptsTreeController : FileSystemTreeController + { + protected override string FilePath + { + get { return SystemDirectories.Scripts + "/"; } + } + + protected override IEnumerable FileSearchPattern + { + get { return UmbracoConfig.For.UmbracoSettings().Content.ScriptFileTypes; } + } + + protected override string EditFormUrl + { + get { return "settings/scripts/editScript.aspx?file={0}"; } + } + + protected override bool EnableCreateOnFolder + { + get { return true; } + } + + protected override void OnRenderFolderNode(TreeNode treeNode) + { + } + + protected override void OnRenderFileNode(TreeNode treeNode, FileInfo file) + { + treeNode.Icon = + file.Name.EndsWith(".js", StringComparison.OrdinalIgnoreCase) ? + "icon-script" : + "icon-code"; + + } + } +} diff --git a/src/Umbraco.Web/Trees/StylesheetsTreeController.cs b/src/Umbraco.Web/Trees/StylesheetsTreeController.cs new file mode 100644 index 0000000000..786bfe45bc --- /dev/null +++ b/src/Umbraco.Web/Trees/StylesheetsTreeController.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net.Http.Formatting; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Core.Models; +using Umbraco.Core.Persistence.Repositories; +using Umbraco.Core.Services; +using Umbraco.Web.Models.Trees; +using Umbraco.Web._Legacy.Actions; +using File = System.IO.File; + +namespace Umbraco.Web.Trees +{ + [Tree(Constants.Applications.Settings, Constants.Trees.Stylesheets, "Stylesheets", "icon-folder", "icon-folder", sortOrder: 3)] + public class StylesheetsTreeController : FileSystemTreeController + { + + protected override string FilePath + { + get { return SystemDirectories.Css + "/"; } + } + + protected override IEnumerable FileSearchPattern + { + get { return new [] {"css"}; } + } + + protected override string EditFormUrl + { + get { return "settings/stylesheet/editStylesheet.aspx?id={0}"; } + } + + protected override bool EnableCreateOnFolder + { + get { return false; } + } + + + protected override void OnBeforeRenderMenu(MenuItemCollection menu, string id, FormDataCollection queryStrings) + { + if (File.Exists((IOHelper.MapPath(FilePath + "/" + id)))) + { + menu.Items.Add(Services.TextService.Localize("actions", ActionNew.Instance.Alias)) + //Since we haven't implemented anything for file systems in angular, this needs to be converted to + //use the legacy format + .ConvertLegacyFileSystemMenuItem(id, "stylesheet", queryStrings.GetValue("application")); + } + } + + protected override void OnAfterRenderMenu(MenuItemCollection menu, string id, FormDataCollection queryStrings) + { + if (File.Exists((IOHelper.MapPath(FilePath + "/" + id)))) + { + menu.Items.Add(Services.TextService.Localize("actions", ActionSort.Instance.Alias), true) + .ConvertLegacyFileSystemMenuItem(id, "stylesheet", queryStrings.GetValue("application")); + + //refresh action + menu.Items.Add( + Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true); + } + } + + protected override void OnRenderFileNode(TreeNode treeNode, FileInfo file) + { + treeNode.Icon = "icon-brackets"; + treeNode.NodeType = "stylesheet"; + var styleSheet = Services.FileService.GetStylesheetByName(treeNode.Id.ToString().EnsureEndsWith(".css")); + if (styleSheet != null) + { + treeNode.HasChildren = styleSheet.Properties.Any(); + } + + } + + protected override TreeNodeCollection GetTreeNodesForFile(string path, string id, FormDataCollection queryStrings) + { + var nodes = new TreeNodeCollection(); + + var sheet = Services.FileService.GetStylesheetByName(id.EnsureEndsWith(".css")); + + foreach (var prop in sheet.Properties) + { + var node = CreateTreeNode( + id + "_" + prop.Name, + id, queryStrings, + prop.Name, + "icon-brackets", + false, + "/" + queryStrings.GetValue("application") + "/framed/" + + Uri.EscapeDataString("settings/stylesheet/property/editStylesheetProperty.aspx?id=" + + sheet.Path + "&prop=" + prop.Name)); + node.NodeType = "stylesheetProperty"; + nodes.Add(node); + + + + } + + return nodes; + } + } +} diff --git a/src/Umbraco.Web/Trees/XsltTreeController.cs b/src/Umbraco.Web/Trees/XsltTreeController.cs new file mode 100644 index 0000000000..0c0bb8f637 --- /dev/null +++ b/src/Umbraco.Web/Trees/XsltTreeController.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Web.Models.Trees; + +namespace Umbraco.Web.Trees +{ + [Tree(Constants.Applications.Settings, Constants.Trees.Xslt, "XSLT Files", "icon-folder", "icon-folder", sortOrder: 2)] + public class XsltTreeController : FileSystemTreeController + { + protected override string FilePath + { + get { return SystemDirectories.Xslt + "/"; } + } + + protected override IEnumerable FileSearchPattern + { + get { return new [] {"xslt"}; } + } + + protected override string EditFormUrl + { + get { return "developer/xslt/editXslt.aspx?file={0}"; } + } + + protected override bool EnableCreateOnFolder + { + get { return false; } + } + + protected override void OnRenderFileNode(TreeNode treeNode, FileInfo file) + { + treeNode.Icon = "icon-code"; + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 2f1dcef7ce..965c1f2531 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -327,7 +327,10 @@ + + + @@ -1047,8 +1050,8 @@ - - + + @@ -1546,16 +1549,11 @@ xml.aspx - - - - - @@ -1759,7 +1757,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/FileSystemTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/FileSystemTree.cs deleted file mode 100644 index aed6009d86..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/FileSystemTree.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System; -using System.Data; -using System.Configuration; -using System.Web; -using System.Web.Security; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.WebControls.WebParts; -using System.Web.UI.HtmlControls; -using System.IO; -using Umbraco.Core.IO; - -namespace umbraco.cms.presentation.Trees -{ - public abstract class FileSystemTree : BaseTree - { - - public FileSystemTree(string application) : base(application) { } - - public override abstract void RenderJS(ref System.Text.StringBuilder Javascript); - protected override abstract void CreateRootNode(ref XmlTreeNode rootNode); - - protected abstract string FilePath { get; } - protected abstract string FileSearchPattern { get; } - - /// - /// Inheritors can override this method to modify the file node that is created. - /// - /// - protected virtual void OnRenderFileNode(ref XmlTreeNode xNode) { } - - /// - /// Inheritors can override this method to modify the folder node that is created. - /// - /// - protected virtual void OnRenderFolderNode(ref XmlTreeNode xNode) { } - - public override void Render(ref XmlTree tree) - { - string orgPath = ""; - string path = ""; - if (!string.IsNullOrEmpty(this.NodeKey)) - { - orgPath = this.NodeKey; - path = IOHelper.MapPath(FilePath + orgPath); - orgPath += "/"; - } - else - { - path = IOHelper.MapPath(FilePath); - } - - DirectoryInfo dirInfo = new DirectoryInfo(path); - - - DirectoryInfo[] dirInfos = dirInfo.Exists ? dirInfo.GetDirectories() : new DirectoryInfo[] { }; - - var args = new TreeEventArgs(tree); - OnBeforeTreeRender(dirInfo, args); - - foreach (DirectoryInfo dir in dirInfos) - { - if ((dir.Attributes & FileAttributes.Hidden) == 0) - { - XmlTreeNode xDirNode = XmlTreeNode.Create(this); - xDirNode.NodeID = orgPath + dir.Name; - xDirNode.Menu.Clear(); - xDirNode.Text = dir.Name; - xDirNode.Action = string.Empty; - xDirNode.Source = GetTreeServiceUrl(orgPath + dir.Name); - xDirNode.Icon = FolderIcon; - xDirNode.OpenIcon = FolderIconOpen; - xDirNode.HasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0; - - OnRenderFolderNode(ref xDirNode); - OnBeforeNodeRender(ref tree, ref xDirNode, EventArgs.Empty); - if (xDirNode != null) - { - tree.Add(xDirNode); - OnAfterNodeRender(ref tree, ref xDirNode, EventArgs.Empty); - } - - - } - } - - //this is a hack to enable file system tree to support multiple file extension look-up - //so the pattern both support *.* *.xml and xml,js,vb for lookups - string[] allowedExtensions = new string[0]; - bool filterByMultipleExtensions = FileSearchPattern.Contains(","); - FileInfo[] fileInfo; - - if (filterByMultipleExtensions) - { - fileInfo = dirInfo.Exists ? dirInfo.GetFiles() : new FileInfo[] {}; - allowedExtensions = FileSearchPattern.ToLower().Split(','); - } - else - { - fileInfo = dirInfo.Exists ? dirInfo.GetFiles(FileSearchPattern) : new FileInfo[] { }; - } - - foreach (FileInfo file in fileInfo) - { - if ((file.Attributes & FileAttributes.Hidden) == 0) - { - if (filterByMultipleExtensions && Array.IndexOf(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0) - continue; - - XmlTreeNode xFileNode = XmlTreeNode.Create(this); - xFileNode.NodeID = orgPath + file.Name; - xFileNode.Text = file.Name; - if (!((orgPath == ""))) - xFileNode.Action = "javascript:openFile('" + orgPath + file.Name + "');"; - else - xFileNode.Action = "javascript:openFile('" + file.Name + "');"; - xFileNode.Icon = "doc.gif"; - xFileNode.OpenIcon = "doc.gif"; - - OnRenderFileNode(ref xFileNode); - OnBeforeNodeRender(ref tree, ref xFileNode, EventArgs.Empty); - if (xFileNode != null) - { - tree.Add(xFileNode); - OnAfterNodeRender(ref tree, ref xFileNode, EventArgs.Empty); - } - - - } - } - OnAfterTreeRender(dirInfo, args); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadScripts.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadScripts.cs deleted file mode 100644 index 296d7b1db4..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadScripts.cs +++ /dev/null @@ -1,92 +0,0 @@ - -using Umbraco.Core.Services; -using System.Collections.Generic; -using System.Text; -using Umbraco.Core; - -using Umbraco.Core.Configuration; -using umbraco.cms.presentation.Trees; -using Umbraco.Core.IO; -using Umbraco.Web.Trees; -using Umbraco.Web._Legacy.Actions; - - -namespace umbraco -{ - [Tree(Constants.Applications.Settings, "scripts", "Scripts", "icon-folder", "icon-folder", sortOrder: 2)] - public class loadScripts : FileSystemTree - { - public loadScripts(string application) : base(application) { } - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - rootNode.NodeType = "init" + TreeAlias; - rootNode.NodeID = "init"; - rootNode.Text = Services.TextService.Localize("treeHeaders/scripts"); - } - - public override void RenderJS(ref StringBuilder Javascript) - { - Javascript.Append( - @" - function openScriptEditor(id) { - UmbClientMgr.contentFrame('settings/scripts/editScript.aspx?file=' + id); - } - function openScriptFolder(id) { - return false; - } - "); - } - - protected override string FilePath - { - get - { - return SystemDirectories.Scripts + "/"; - } - } - - protected override string FileSearchPattern - { - - get { return string.Join(",", UmbracoConfig.For.UmbracoSettings().Content.ScriptFileTypes); } - } - - protected override void OnRenderFolderNode(ref XmlTreeNode xNode) - { - - xNode.Menu = new List(new IAction[] - { - ActionNew.Instance, - ContextMenuSeperator.Instance, - ActionDelete.Instance, - ContextMenuSeperator.Instance, - ActionRefresh.Instance - }); - xNode.Action = "javascript:void(0)"; - xNode.NodeType = "scriptsFolder"; - xNode.Action = "javascript:void(0);"; - } - - protected override void OnRenderFileNode(ref XmlTreeNode xNode) - { - xNode.Action = xNode.Action.Replace("openFile", "openScriptEditor"); - - // add special icons for javascript files - if (xNode.Text.Contains(".js")) - { - xNode.Icon = "icon-script"; - xNode.OpenIcon = "icon-script"; - } - else - { - xNode.Icon = "icon-code"; - xNode.OpenIcon = "icon-code"; - } - - xNode.Text = xNode.Text.StripFileExtension(); - } - - - } - -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheetProperty.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheetProperty.cs deleted file mode 100644 index 372b490e9a..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheetProperty.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Globalization; -using System.Text; -using System.Web; - -using umbraco.cms.businesslogic.web; -using umbraco.cms.presentation.Trees; -using Umbraco.Core; -using Umbraco.Web.Trees; - - -namespace umbraco -{ - [Tree(Constants.Applications.Settings, "stylesheetProperty", "Stylesheet Property", "", "", initialize: false)] - public class loadStylesheetProperty : BaseTree - { - public loadStylesheetProperty(string application) : base(application) { } - - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - rootNode.NodeType = "init" + TreeAlias; - rootNode.NodeID = "init"; - } - - public override void RenderJS(ref StringBuilder Javascript) - { - Javascript.Append( - @" - function openStylesheetProperty(name, prop) { - UmbClientMgr.contentFrame('settings/stylesheet/property/editStylesheetProperty.aspx?id=' + name + '&prop=' + prop); - } - "); - } - - public override void Render(ref XmlTree tree) - { - var sheet = Services.FileService.GetStylesheetByName(NodeKey.EnsureEndsWith(".css")); - - foreach (var prop in sheet.Properties) - { - var sheetId = sheet.Path.TrimEnd(".css"); - var xNode = XmlTreeNode.Create(this); - xNode.NodeID = sheetId + "_" + prop.Name; - xNode.Text = prop.Name; - xNode.Action = "javascript:openStylesheetProperty('" + - //Needs to be escaped for JS - HttpUtility.UrlEncode(sheet.Path) + - "','" + prop.Name + "');"; - xNode.Icon = "icon-brackets"; - xNode.OpenIcon = "icon-brackets"; - - OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); - if (xNode != null) - { - tree.Add(xNode); - OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); - } - - } - } - - } - -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheets.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheets.cs deleted file mode 100644 index 649212315e..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadStylesheets.cs +++ /dev/null @@ -1,74 +0,0 @@ -using Umbraco.Core.Services; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Web; -using umbraco.cms.presentation.Trees; -using Umbraco.Core; -using Umbraco.Web.Trees; -using Umbraco.Web._Legacy.Actions; - - -namespace umbraco -{ - [Tree(Constants.Applications.Settings, Constants.Trees.Stylesheets, "Stylesheets")] - public class loadStylesheets : BaseTree - { - public loadStylesheets(string application) : base(application) { } - - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - rootNode.NodeType = "init" + TreeAlias; - rootNode.NodeID = "init"; - rootNode.Text = Services.TextService.Localize("treeHeaders/stylesheets"); - } - - public override void RenderJS(ref StringBuilder Javascript) - { - Javascript.Append( - @" - function openStylesheet(name) { - UmbClientMgr.contentFrame('settings/stylesheet/editStylesheet.aspx?id=' + name); - } - "); - } - - protected override void CreateAllowedActions(ref List actions) - { - actions.Clear(); - actions.AddRange(new IAction[] { ActionNew.Instance, ActionDelete.Instance, - ActionSort.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance }); - } - - public override void Render(ref XmlTree tree) - { - foreach (var sheet in Services.FileService.GetStylesheets()) - { - var nodeId = sheet.Path.TrimEnd(".css"); - var xNode = XmlTreeNode.Create(this); - xNode.NodeID = nodeId; - xNode.Text = nodeId; - xNode.Action = "javascript:openStylesheet('" + - //Needs to be escaped for JS - HttpUtility.UrlEncode(sheet.Path) + "');"; - var styleSheetPropertyTree = new loadStylesheetProperty(this.app); - xNode.Source = styleSheetPropertyTree.GetTreeServiceUrl(nodeId); - xNode.HasChildren = sheet.Properties.Any(); - xNode.Icon = " icon-brackets"; - xNode.OpenIcon = "icon-brackets"; - xNode.NodeType = "stylesheet"; //this shouldn't be like this, it should be this.TreeAlias but the ui.config file points to this name. - - OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); - if (xNode != null) - { - tree.Add(xNode); - OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); - } - - } - } - - } - -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadXslt.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadXslt.cs deleted file mode 100644 index 46fbb8c2cd..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadXslt.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using umbraco.cms.presentation.Trees; -using Umbraco.Core.IO; -using Umbraco.Core; -using Umbraco.Web.Trees; -using Umbraco.Web._Legacy.Actions; - -namespace umbraco -{ - /// - /// Handles loading of the xslt files into the application tree - /// - [Tree(Constants.Applications.Developer, "xslt", "XSLT Files", sortOrder: 5)] - public class loadXslt : FileSystemTree - { - - public loadXslt(string application) : base(application) { } - - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - rootNode.NodeType = "init" + TreeAlias; - rootNode.NodeID = "init"; - } - - /// - /// Renders the Javascript - /// - /// The javascript. - public override void RenderJS(ref StringBuilder Javascript) - { - Javascript.Append( - @" -function openXslt(id) { - UmbClientMgr.contentFrame('developer/xslt/editXslt.aspx?file=' + id); -} -"); - } - - protected override string FilePath - { - get { return SystemDirectories.Xslt + "/"; } - } - - protected override string FileSearchPattern - { - get { return "*.xslt"; } - } - - protected override void OnRenderFileNode(ref XmlTreeNode xNode) - { - xNode.Action = xNode.Action.Replace("openFile", "openXslt"); - xNode.Icon = "icon-code"; - xNode.OpenIcon = "icon-code"; - - xNode.Text = xNode.Text.StripFileExtension(); - } - - protected override void OnRenderFolderNode(ref XmlTreeNode xNode) - { - xNode.Menu = new List(new IAction[] { ActionDelete.Instance, ContextMenuSeperator.Instance, ActionRefresh.Instance }); - xNode.NodeType = "xsltFolder"; - } - } - -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Xslt/editXslt.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Xslt/editXslt.aspx.cs index 32aee74725..f1ad0e705d 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Xslt/editXslt.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Xslt/editXslt.aspx.cs @@ -30,7 +30,7 @@ namespace umbraco.cms.presentation.developer string file = Request.QueryString["file"]; string path = BaseTree.GetTreePathFromFilePath(file); ClientTools - .SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree().Tree.Alias) + .SetActiveTreeType(Constants.Trees.Xslt) .SyncTree(path, false); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs index b6db5cdf8c..cd6d7159aa 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/scripts/editScript.aspx.cs @@ -65,7 +65,7 @@ namespace umbraco.cms.presentation.settings.scripts if (IsPostBack == false) { ClientTools - .SetActiveTreeType(TreeDefinitionCollection.Instance.FindTree().Tree.Alias) + .SetActiveTreeType(Constants.Trees.Scripts) .SyncTree(ScriptTreeSyncPath, false); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/editstylesheet.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/editstylesheet.aspx.cs index 5d24cef82a..9b2a5590ce 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/editstylesheet.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/editstylesheet.aspx.cs @@ -60,7 +60,7 @@ namespace umbraco.cms.presentation.settings.stylesheet lttPath.Text = "" + stylesheet.VirtualPath + ""; editorSource.Text = stylesheet.Content; - TreeSyncPath = BaseTree.GetTreePathFromFilePath(filename).TrimEnd(".css"); + TreeSyncPath = BaseTree.GetTreePathFromFilePath(filename); // name derives from path, without the .css extension, clean for xss NameTxt.Text = stylesheet.Path.TrimEnd(".css").CleanForXss('\\', '/'); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/property/EditStyleSheetProperty.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/property/EditStyleSheetProperty.aspx.cs index eb284c5ea5..780f63e469 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/property/EditStyleSheetProperty.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/stylesheet/property/EditStyleSheetProperty.aspx.cs @@ -41,7 +41,7 @@ namespace umbraco.cms.presentation.settings.stylesheet protected override void OnLoad(EventArgs e) { base.OnLoad(e); - + _sheet = Services.FileService.GetStylesheetByName(Request.QueryString["id"]); if (_sheet == null) throw new InvalidOperationException("No stylesheet found with name: " + Request.QueryString["id"]); @@ -70,9 +70,9 @@ namespace umbraco.cms.presentation.settings.stylesheet prStyles.Attributes["style"] = _stylesheetproperty.Value; - var nodePath = string.Format("-1,init,{0},{0}_{1}", _sheet.Path - //needs a double escape to work with JS - .Replace("\\", "\\\\").TrimEnd(".css"), _stylesheetproperty.Name); + var path = _sheet.Path.Replace('\\', '/'); + var nodePath = string.Format(BaseTree.GetTreePathFromFilePath(path) + + ",{0}_{1}", path, _stylesheetproperty.Name); ClientTools .SetActiveTreeType(Constants.Trees.Stylesheets)