From ecdfecd17331c36296aaff4c9f079bf1393180c3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 4 Sep 2013 20:06:41 +1000 Subject: [PATCH] Fixed the dialog service to be able to call registered callbacks even if the dialog is an iframe, this helps fix the legacy tree pickers, fixed up the legacy tree control so that it can load in new trees as well --- .../lib/umbraco/LegacyUmbClientMgr.js | 70 ++++++------------- .../src/common/services/dialog.service.js | 27 +++++-- .../Trees/LegacyTreeDataConverter.cs | 42 ++++++----- .../umbraco/controls/Tree/TreeControl.ascx.cs | 25 ++++--- 4 files changed, 84 insertions(+), 80 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js index c1fe7ebab8..da0221cfe5 100644 --- a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js +++ b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js @@ -165,8 +165,12 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); //get our angular navigation service var injector = getRootInjector(); - var dialogService = injector.get("dialogService"); - + var dialogService = injector.get("dialogService"); + + var self = this; + + //TODO: need to get the closeTriggers working for compatibility too somehow. + var dialog = dialogService.open({ template: url, width: width, @@ -174,57 +178,29 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); iframe: true, show: true, callback: function (result) { + + if (typeof onCloseCallback == "function") { + onCloseCallback.apply(self, [result]); + } + dialog.hide(); } - }); - - // var m = new Umbraco.Controls.ModalWindow(); - // this._modal.push(m); - // m.open(url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback); - - //throw "Not implemented!"; - - ////if this is the top window, or if the top window doesn't have a client manager, create the modal in this manager - //if (window == this.mainWindow() || !this.mainWindow().UmbClientMgr) { - // var m = new Umbraco.Controls.ModalWindow(); - // this._modal.push(m); - // m.open(url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback); - //} - //else { - // //if the main window has a client manager, then call the main window's open modal method whilst keeping the context of it's manager. - // if (this.mainWindow().UmbClientMgr) { - // this.mainWindow().UmbClientMgr.openModalWindow.apply(this.mainWindow().UmbClientMgr, - // [url, name, showHeader, width, height, top, leftOffset, closeTriggers, onCloseCallback]); - // } - // else { - // return; //exit recurse. - // } - //} + }); + + return dialog; }, closeModalWindow: function(rVal) { - getRootScope().$emit("closeDialogs"); + if (rVal) { + //trigger the closeDialogs event with arguments, note: using the term 'outVal' since that is what is expected in the tree picker. + getRootScope().$emit("closeDialogs", { outVal: rVal }); + } + else { + //no arg vals + getRootScope().$emit("closeDialogs"); + } + - //if (this._modal != null && this._modal.length > 0) { - // this._modal.pop().close(rVal); - //} - //else { - // //this will recursively try to close a modal window until the parent window has a modal object or the window is the top and has the modal object - // var mgr = null; - // if (window.parent == null || window.parent == window) { - // //we are at the root window, check if we can close the modal window from here - // if (window.UmbClientMgr != null && window.UmbClientMgr._modal != null && window.UmbClientMgr._modal.length > 0) { - // mgr = window.UmbClientMgr; - // } - // else { - // return; //exit recursion. - // } - // } - // else if (typeof window.parent.UmbClientMgr != "undefined") { - // mgr = window.parent.UmbClientMgr; - // } - // mgr.closeModalWindow.call(mgr, rVal); - //} }, _debug: function(strMsg) { if (this._isDebug) { diff --git a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js index d7d5a34734..327f6d54c8 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js @@ -34,16 +34,25 @@ angular.module('umbraco.services') var dialogs = []; /** Internal method that removes all dialogs */ - function removeAllDialogs() { + function removeAllDialogs(args) { for (var i = 0; i < dialogs.length; i++) { var dialog = dialogs[i]; - removeDialog(dialog); + removeDialog(dialog, args); dialogs.splice(i, 1); } } /** Internal method that handles closing a specific dialog */ - function removeDialog(dialog) { + function removeDialog(dialog, args) { + + //if there's arguments passed in then check if there's a callback registered in the current modal then call it. + //this occurs when the "closeDialogs" event is triggered with arguments. + + if (args && dialog.data("modalCb") != null && angular.isFunction(dialog.data("modalCb"))) { + var cb = dialog.data("modalCb"); + cb.apply(dialog, [args]); + } + dialog.modal("hide"); $timeout(function () { @@ -72,9 +81,7 @@ angular.module('umbraco.services') //Modal dom obj and unique id var $modal = $('
'); var id = templateUrl.replace('.html', '').replace('.aspx', '').replace(/[\/|\.|:\&\?\=]/g, "-") + '-' + scope.$id; - - if(options.inline){ animationClass = ""; modalClass = ""; @@ -115,6 +122,9 @@ angular.module('umbraco.services') $modal.modal('show'); } + //store the callback in the modal jquery data + $modal.data("modalCb", callback); + return $modal; } else { @@ -133,6 +143,9 @@ angular.module('umbraco.services') //append to body or other container element container.append($modal); + //store the callback in the modal jquery data + $modal.data("modalCb", callback); + // Compile modal content $timeout(function() { $compile($modal)(scope); @@ -207,8 +220,8 @@ angular.module('umbraco.services') } /** Handles the closeDialogs event */ - $rootScope.$on("closeDialogs", function () { - removeAllDialogs(); + $rootScope.$on("closeDialogs", function (evt, args) { + removeAllDialogs(args); }); return { diff --git a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs index 622136a1ac..8d165b9374 100644 --- a/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs +++ b/src/Umbraco.Web/Trees/LegacyTreeDataConverter.cs @@ -48,21 +48,11 @@ namespace Umbraco.Web.Trees /// internal class LegacyTreeDataConverter { - /// - /// This is used by any legacy services that require rendering a BaseTree, if a new controller tree is detected it will try to invoke it's legacy predecessor. - /// - /// - /// - /// - internal static BaseTree GetLegacyTreeForLegacyServices(ApplicationTreeService appTreeService, string treeType) + internal static BaseTree GetLegacyTreeForLegacyServices(Core.Models.ApplicationTree appTree) { - BaseTree tree; + if (appTree == null) throw new ArgumentNullException("appTree"); - //first get the app tree definition so we can then figure out if we need to load by legacy or new - //now we'll look up that tree - var appTree = appTreeService.GetByAlias(treeType); - if (appTree == null) - throw new InvalidOperationException("No tree found with alias " + treeType); + BaseTree tree; var controllerAttempt = appTree.TryGetControllerTree(); if (controllerAttempt.Success) @@ -70,14 +60,14 @@ namespace Umbraco.Web.Trees var legacyAtt = controllerAttempt.Result.GetCustomAttribute(false); if (legacyAtt == null) { - LogHelper.Warn("Cannot render tree: " + treeType + ". Cannot render a " + typeof(TreeApiController) + " tree type with the legacy web services unless attributed with " + typeof(LegacyBaseTreeAttribute)); + LogHelper.Warn("Cannot render tree: " + appTree.Alias + ". Cannot render a " + typeof(TreeApiController) + " tree type with the legacy web services unless attributed with " + typeof(LegacyBaseTreeAttribute)); return null; } var treeDef = new TreeDefinition( legacyAtt.BaseTreeType, new ApplicationTree(false, true, appTree.SortOrder, appTree.ApplicationAlias, appTree.Alias, appTree.Title, appTree.IconClosed, appTree.IconOpened, "", legacyAtt.BaseTreeType.GetFullNameWithAssembly(), ""), - new Application(treeType, treeType, "", 0)); + new Application(appTree.Alias, appTree.Alias, "", 0)); tree = treeDef.CreateInstance(); tree.TreeAlias = appTree.Alias; @@ -86,7 +76,7 @@ namespace Umbraco.Web.Trees else { //get the tree that we need to render - var treeDef = TreeDefinitionCollection.Instance.FindTree(treeType); + var treeDef = TreeDefinitionCollection.Instance.FindTree(appTree.Alias); if (treeDef == null) { return null; @@ -97,6 +87,26 @@ namespace Umbraco.Web.Trees return tree; } + /// + /// This is used by any legacy services that require rendering a BaseTree, if a new controller tree is detected it will try to invoke it's legacy predecessor. + /// + /// + /// + /// + internal static BaseTree GetLegacyTreeForLegacyServices(ApplicationTreeService appTreeService, string treeType) + { + if (appTreeService == null) throw new ArgumentNullException("appTreeService"); + if (treeType == null) throw new ArgumentNullException("treeType"); + + //first get the app tree definition so we can then figure out if we need to load by legacy or new + //now we'll look up that tree + var appTree = appTreeService.GetByAlias(treeType); + if (appTree == null) + throw new InvalidOperationException("No tree found with alias " + treeType); + + return GetLegacyTreeForLegacyServices(appTree); + } + /// /// Gets the menu item collection from a legacy tree node based on it's parent node's child collection /// diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/TreeControl.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/TreeControl.ascx.cs index 6ac15e4b1a..f31b395079 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/TreeControl.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/Tree/TreeControl.ascx.cs @@ -5,7 +5,9 @@ using System.Web.UI; using System.Web.UI.WebControls; using System.Web.Script.Serialization; using Umbraco.Core.Logging; +using Umbraco.Core.Models; using Umbraco.Web.Trees; +using Umbraco.Web.UI.Controls; using umbraco.interfaces; using System.Text.RegularExpressions; using umbraco.BusinessLogic.Actions; @@ -15,7 +17,6 @@ using umbraco.cms.presentation.Trees; using umbraco.BasePages; using System.Web.Services; using System.Drawing; -using umbraco.BusinessLogic; using System.Linq; using Umbraco.Core; @@ -26,7 +27,7 @@ namespace umbraco.controls.Tree /// The Umbraco tree control. /// If this control doesn't exist on an UmbracoEnsuredPage it will not work. /// - public partial class TreeControl : System.Web.UI.UserControl, ITreeService + public partial class TreeControl : UmbracoUserControl, ITreeService { /// @@ -59,7 +60,7 @@ namespace umbraco.controls.Tree private List m_ActiveTrees = new List(); private List m_AllAppTrees = new List(); - private List m_ActiveTreeDefs = null; + private List m_ActiveTreeDefs = null; private TreeMode m_TreeType = TreeMode.Standard; private bool m_IsInit = false; private TreeService m_TreeService = new TreeService(); @@ -223,27 +224,31 @@ namespace umbraco.controls.Tree //find all tree definitions that have the current application alias that are ACTIVE. //if an explicit tree has been requested, then only load that tree in. - m_ActiveTreeDefs = TreeDefinitionCollection.Instance.FindActiveTrees(GetCurrentApp()); + //m_ActiveTreeDefs = TreeDefinitionCollection.Instance.FindActiveTrees(GetCurrentApp()); + + m_ActiveTreeDefs = Services.ApplicationTreeService.GetApplicationTrees(GetCurrentApp(), true).ToList(); + if (!string.IsNullOrEmpty(this.TreeType)) { m_ActiveTreeDefs = m_ActiveTreeDefs - .Where(x => x.Tree.Alias == this.TreeType) + .Where(x => x.Alias == this.TreeType) .ToList(); //this will only return 1 } //find all tree defs that exists for the current application regardless of if they are active - List appTreeDefs = TreeDefinitionCollection.Instance.FindTrees(GetCurrentApp()); + var appTreeDefs = Services.ApplicationTreeService.GetApplicationTrees(GetCurrentApp()).ToList(); //Create the BaseTree's based on the tree definitions found - foreach (TreeDefinition treeDef in appTreeDefs) + foreach (var treeDef in appTreeDefs) { //create the tree and initialize it - BaseTree bTree = treeDef.CreateInstance(); + var bTree = LegacyTreeDataConverter.GetLegacyTreeForLegacyServices(treeDef); + //BaseTree bTree = treeDef.CreateInstance(); bTree.SetTreeParameters(m_TreeService); //store the created tree m_AllAppTrees.Add(bTree); - if (treeDef.Tree.Initialize) + if (treeDef.Initialize) m_ActiveTrees.Add(bTree); } @@ -359,7 +364,7 @@ namespace umbraco.controls.Tree //stand alone tree, so we'll just add a TreeType to the TreeService and ensure that the right method gets loaded in tree.aspx if (m_ActiveTrees.Count == 1) { - m_TreeService.TreeType = m_ActiveTreeDefs[0].Tree.Alias; + m_TreeService.TreeType = m_ActiveTreeDefs[0].Alias; //convert the menu to a string //string initActions = (TreeSvc.ShowContextMenu ? Action.ToString(m_ActiveTrees[0].RootNodeActions) : "");