From b53400cecab9f40c18f0162194082ba8566e9433 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 13 Apr 2018 00:09:28 +1000 Subject: [PATCH 01/10] Fixes up promise chains for the tree, adds logic to the tree picker to track the deepest paths expanded and then when a language is changed, we reload the tree with the new language and also sync all paths so the user can continue where they left off but with the new language nodes. --- .../components/tree/umbtree.directive.js | 24 +++--- .../src/common/services/tree.service.js | 17 ++--- .../treepicker/treepicker.controller.js | 76 ++++++++++++++++++- 3 files changed, 96 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js index 335d27d5c4..08c0cc08c2 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js @@ -90,7 +90,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat scope.eventhandler.load = function (section) { scope.section = section; - loadTree(); + return loadTree(); }; scope.eventhandler.reloadNode = function (node) { @@ -100,8 +100,10 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat } if (node) { - scope.loadChildren(node, true); - } + return scope.loadChildren(node, true); + } + + return $q.reject(); }; /** @@ -267,7 +269,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat args["queryString"] = scope.customtreeparams; } - treeService.getTree(args) + return treeService.getTree(args) .then(function (data) { //set the data once we have it scope.tree = data; @@ -280,11 +282,15 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat scope.activeTree = scope.tree.root; emitEvent("treeLoaded", { tree: scope.tree }); emitEvent("treeNodeExpanded", { tree: scope.tree, node: scope.tree.root, children: scope.tree.root.children }); - + return $q.when(data); }, function (reason) { scope.loading = false; - notificationsService.error("Tree Error", reason); + notificationsService.error("Tree Error", reason); + return $q.reject(reason); }); + } + else { + return $q.reject(); } } @@ -420,8 +426,8 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat emitEvent("treeNodeAltSelect", { element: elem, tree: scope.tree, node: n, event: ev }); }; - //watch for section changes and customtreeparams changes - scope.$watchCollection("[section, customtreeparams]", function (newVal, oldVal) { + //watch for section changes + scope.$watch("section", function (newVal, oldVal) { if (!scope.tree) { loadTree(); @@ -441,7 +447,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat lastSection = newVal; } }); - + setupExternalEvents(); loadTree(); }; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js index 888a067a66..859ffba037 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js @@ -475,8 +475,6 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS */ getTree: function (args) { - var deferred = $q.defer(); - //set defaults if (!args) { args = { section: 'content', cacheKey: null }; @@ -489,12 +487,11 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS //return the cache if it exists if (cacheKey && treeCache[cacheKey] !== undefined) { - deferred.resolve(treeCache[cacheKey]); - return deferred.promise; + return $q.when(treeCache[cacheKey]); } var self = this; - treeResource.loadApplication(args) + return treeResource.loadApplication(args) .then(function(data) { //this will be called once the tree app data has loaded var result = { @@ -507,16 +504,14 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS //cache this result if a cache key is specified - generally a cache key should ONLY // be specified for application trees, dialog trees should not be cached. - if (cacheKey) { + if (cacheKey) { treeCache[cacheKey] = result; - deferred.resolve(treeCache[cacheKey]); + return $q.when(treeCache[cacheKey]); } //return un-cached - deferred.resolve(result); + return $q.when(result); }); - - return deferred.promise; }, /** @@ -791,4 +786,4 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS }; } -angular.module('umbraco.services').factory('treeService', treeService); \ No newline at end of file +angular.module('umbraco.services').factory('treeService', treeService); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index 2faf4ebaa5..cd5872f2ab 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -23,6 +23,8 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", // Search and listviews is only working for content, media and member section var searchableSections = ["content", "media", "member"]; + // tracks all expanded paths so when the language is switched we can resync it with the already loaded paths + var expandedPaths = []; var vm = this; vm.treeReady = false; @@ -188,14 +190,86 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", vm.selectedLanguage = language; // close the language selector vm.languageSelectorIsOpen = false; - initTree(); + + initTree(); //this will reset the tree params and the tree directive will pick up the changes in a $watch + + $timeout(function () { //execute in the next digest since the $watch needs to update first + + //reload the tree with it's updated querystring args + vm.dialogTreeEventHandler.load(vm.section).then(function () { + + //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in + //sequence but that's what we need to do here + + //create the list of promises + var promises = []; + for (var i = 0; i < expandedPaths.length; i++) { + promises.push(vm.dialogTreeEventHandler.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + } + + //now execute them in sequence... sorry there's no other good way to do it with angular promises + var j = 0; + function pExec(promise) { + j++; + promise.then(function (data) { + if (j === promises.length) { + return $q.when(data); //exit + } + else { + return pExec(promises[j]); //recurse + } + }); + } + pExec(promises[0]); //start the promise chain + }); + }); }; function toggleLanguageSelector() { vm.languageSelectorIsOpen = !vm.languageSelectorIsOpen; }; + + function trackExpandedPaths(node) { + + if (!node.children || !angular.isArray(node.children) || node.children.length == 0) { + return; + } + + //take the last child + var childPath = treeService.getPath(node.children[node.children.length - 1]).join(","); + //check if this already exists, if so exit + if (expandedPaths.indexOf(childPath) !== -1) { + return; + } + + if (expandedPaths.length === 0) { + expandedPaths.push(childPath); //track it + return; + } + + var clonedPaths = expandedPaths.slice(0); //make a copy to iterate over so we can modify the original in the iteration + + _.each(clonedPaths, function (p) { + if (childPath.startsWith(p + ",")) { + //this means that the node's path supercedes this path stored so we can remove the current 'p' and replace it with node.path + expandedPaths.splice(expandedPaths.indexOf(p), 1); //remove it + expandedPaths.push(childPath); //replace it + } + else if (p.startsWith(childPath + ",")) { + //this means we've already tracked a deeper node so we shouldn't track this one + } + else { + expandedPaths.push(childPath); //track it + } + }); + } function nodeExpandedHandler(ev, args) { + + //store the reference to the expanded node path + if (args.node) { + trackExpandedPaths(args.node); + } // open mini list view for list views if (args.node.metaData.isContainer) { From a92361bd00472793b42797782a584f76b67daca9 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 16 Apr 2018 23:07:00 +1000 Subject: [PATCH 02/10] Tree refactor, cleanup legacy support, remove odd jquery callback object, removes unused files, removes publish dialog --- .../lib/umbraco/LegacyUmbClientMgr.js | 9 +- .../components/events/events.directive.js | 7 +- .../components/tree/umbtree.directive.js | 713 +++++++++--------- .../components/tree/umbtreeitem.directive.js | 34 +- .../src/common/services/events.service.js | 5 +- .../src/common/services/navigation.service.js | 141 +--- .../src/common/services/user.service.js | 23 +- .../src/controllers/main.controller.js | 5 + .../src/controllers/navigation.controller.js | 106 ++- src/Umbraco.Web.UI.Client/src/init.js | 66 +- .../common/dialogs/linkpicker.controller.js | 24 +- .../src/views/common/dialogs/linkpicker.html | 3 +- .../dialogs/membergrouppicker.controller.js | 15 +- .../common/dialogs/membergrouppicker.html | 7 +- .../common/dialogs/treepicker.controller.js | 21 +- .../src/views/common/dialogs/treepicker.html | 3 +- .../common/overlays/copy/copy.controller.js | 16 +- .../src/views/common/overlays/copy/copy.html | 3 +- .../linkpicker/linkpicker.controller.js | 21 +- .../overlays/linkpicker/linkpicker.html | 3 +- .../membergrouppicker.controller.js | 16 +- .../membergrouppicker/membergrouppicker.html | 3 +- .../common/overlays/move/move.controller.js | 17 +- .../src/views/common/overlays/move/move.html | 3 +- .../treepicker/treepicker.controller.js | 44 +- .../overlays/treepicker/treepicker.html | 5 +- .../application/umb-navigation.html | 5 +- .../views/content/content.copy.controller.js | 17 +- .../views/content/content.move.controller.js | 21 +- .../src/views/content/copy.html | 5 +- .../src/views/content/move.html | 5 +- .../src/views/datatypes/move.controller.js | 13 +- .../src/views/datatypes/move.html | 3 +- .../views/documenttypes/copy.controller.js | 14 +- .../src/views/documenttypes/copy.html | 3 +- .../views/documenttypes/move.controller.js | 14 +- .../src/views/documenttypes/move.html | 3 +- .../src/views/media/media.move.controller.js | 21 +- .../src/views/media/move.html | 3 +- .../src/views/mediatypes/copy.controller.js | 13 +- .../src/views/mediatypes/copy.html | 3 +- .../src/views/mediatypes/move.controller.js | 14 +- .../src/views/mediatypes/move.html | 3 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 25 - .../umbraco/Views/Default.cshtml | 2 +- .../umbraco/actions/delete.aspx | 30 - .../umbraco/actions/editContent.aspx | 16 - .../umbraco/actions/preview.aspx | 16 - .../umbraco/actions/publish.aspx | 30 - .../umbraco/dialogs/Publish.aspx.cs | 38 - .../umbraco/dialogs/Publish.aspx.designer.cs | 51 -- .../umbraco/dialogs/publish.aspx | 98 --- .../umbraco/settings/EditTemplate.aspx.cs | 11 - .../settings/EditTemplate.aspx.designer.cs | 24 - .../umbraco/settings/editLanguage.aspx | 19 - .../umbraco/settings/editTemplate.aspx | 167 ---- .../umbraco_client/Dialogs/PublishDialog.css | 27 - .../umbraco_client/Dialogs/PublishDialog.js | 98 --- .../Editors/DirectoryBrowser.css | 28 - .../umbraco_client/Editors/EditMacro.css | 36 - .../umbraco_client/Editors/EditStyleSheet.js | 109 --- .../umbraco_client/Editors/EditTemplate.js | 181 ----- .../umbraco_client/Editors/EditView.js | 288 ------- .../umbraco_client/Editors/EditXslt.css | 14 - .../umbraco_client/Editors/EditXslt.js | 80 -- .../umbraco_client/PunyCode/punycode.min.js | 2 - .../Trees/ContentTreeController.cs | 1 - src/Umbraco.Web/UI/Pages/ClientTools.cs | 20 - src/Umbraco.Web/Umbraco.Web.csproj | 41 - .../_Legacy/Actions/ActionPublish.cs | 4 +- .../umbraco/actions/delete.aspx | 30 - .../umbraco/actions/delete.aspx.cs | 39 - .../umbraco/actions/delete.aspx.designer.cs | 78 -- .../umbraco/actions/editContent.aspx | 16 - .../umbraco/actions/editContent.aspx.cs | 27 - .../actions/editContent.aspx.designer.cs | 31 - .../umbraco/actions/preview.aspx | 16 - .../umbraco/actions/preview.aspx.cs | 27 - .../umbraco/actions/preview.aspx.designer.cs | 31 - .../umbraco/actions/publish.aspx | 30 - .../umbraco/actions/publish.aspx.cs | 88 --- .../umbraco/actions/publish.aspx.designer.cs | 78 -- .../developer/Macros/editMacro.aspx.cs | 2 - .../developer/Packages/editPackage.aspx.cs | 2 - .../umbraco/developer/Xslt/editXslt.aspx.cs | 1 - .../settings/EditDictionaryItem.aspx.cs | 1 - .../umbraco/settings/editLanguage.aspx | 19 - .../umbraco/settings/editLanguage.aspx.cs | 107 --- .../settings/editLanguage.aspx.designer.cs | 51 -- .../stylesheet/editstylesheet.aspx.cs | 1 - .../property/EditStyleSheetProperty.aspx.cs | 4 +- 91 files changed, 706 insertions(+), 2902 deletions(-) delete mode 100644 src/Umbraco.Web.UI/umbraco/actions/delete.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/actions/editContent.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/actions/preview.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/actions/publish.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.designer.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/settings/editLanguage.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/settings/editTemplate.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/DirectoryBrowser.css delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/EditMacro.css delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/EditStyleSheet.js delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.css delete mode 100644 src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.js delete mode 100644 src/Umbraco.Web.UI/umbraco_client/PunyCode/punycode.min.js delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.designer.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.designer.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.designer.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.designer.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.designer.cs diff --git a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js index 84651510be..8f1b53082d 100644 --- a/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js +++ b/src/Umbraco.Web.UI.Client/lib/umbraco/LegacyUmbClientMgr.js @@ -90,11 +90,6 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); //mimic the API of the legacy tree var tree = { - setActiveTreeType: function (treeType) { - angularHelper.safeApply($rootScope, function() { - navService._setActiveTreeType(treeType); - }); - }, syncTree: function (path, forceReload) { angularHelper.safeApply($rootScope, function() { navService._syncPath(path, forceReload); @@ -118,9 +113,7 @@ Umbraco.Sys.registerNamespace("Umbraco.Application"); }); }, refreshTree: function (treeAlias) { - angularHelper.safeApply($rootScope, function() { - navService._setActiveTreeType(treeAlias, true); - }); + //no-op, just needs to be here for legacy reasons }, moveNode: function (id, path) { angularHelper.safeApply($rootScope, function() { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/events/events.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/events/events.directive.js index 6f4111373d..3a467807a3 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/events/events.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/events/events.directive.js @@ -214,7 +214,7 @@ angular.module('umbraco.directives') }; }) -.directive('onRightClick',function(){ +.directive('onRightClick',function($parse){ document.oncontextmenu = function (e) { if(e.target.hasAttribute('on-right-click')) { @@ -228,7 +228,10 @@ angular.module('umbraco.directives') el.on('contextmenu',function(e){ e.preventDefault(); e.stopPropagation(); - scope.$apply(attrs.onRightClick); + var fn = $parse(attrs.onRightClick); + scope.$apply(function () { + fn(scope, { $event: event }); + }); return false; }); }; diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js index 08c0cc08c2..c1a8b4b8a0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js @@ -20,10 +20,12 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat onlyinitialized: '@', //Custom query string arguments to pass in to the tree as a string, example: "startnodeid=123&something=value" customtreeparams: '@', - eventhandler: '=', enablecheckboxes: '@', enablelistviewsearch: '@', - enablelistviewexpand: '@' + enablelistviewexpand: '@', + + api: '=?', + onInit: '&?' }, compile: function (element, attrs) { @@ -37,7 +39,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat '' + ''; template += '' + '' + ''; @@ -46,411 +48,382 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat return function (scope, elem, attr, controller) { - //flag to track the last loaded section when the tree 'un-loads'. We use this to determine if we should - // re-load the tree again. For example, if we hover over 'content' the content tree is shown. Then we hover - // outside of the tree and the tree 'un-loads'. When we re-hover over 'content', we don't want to re-load the - // entire tree again since we already still have it in memory. Of course if the section is different we will - // reload it. This saves a lot on processing if someone is navigating in and out of the same section many times - // since it saves on data retreival and DOM processing. - var lastSection = ""; - - //setup a default internal handler - if (!scope.eventhandler) { - scope.eventhandler = $({}); - } - - //flag to enable/disable delete animations - var deleteAnimations = false; - - - /** Helper function to emit tree events */ - function emitEvent(eventName, args) { - if (scope.eventhandler) { - $(scope.eventhandler).trigger(eventName, args); - } - } - - /** This will deleteAnimations to true after the current digest */ - function enableDeleteAnimations() { - //do timeout so that it re-enables them after this digest - $timeout(function () { - //enable delete animations - deleteAnimations = true; - }, 0, false); - } - - - /*this is the only external interface a tree has */ - function setupExternalEvents() { - if (scope.eventhandler) { - - scope.eventhandler.clearCache = function (section) { - treeService.clearCache({ section: section }); - }; - - scope.eventhandler.load = function (section) { - scope.section = section; - return loadTree(); - }; - - scope.eventhandler.reloadNode = function (node) { - - if (!node) { - node = scope.currentNode; - } - - if (node) { - return scope.loadChildren(node, true); - } + }; + }, - return $q.reject(); - }; + controller: function ($scope) { + + var vm = this; + + var registeredCallbacks = { + treeNodeExpanded: [], + treeNodeSelect: [], + treeLoaded: [], + treeSynced: [], + treeOptionsClick: [], + treeNodeAltSelect: [] + }; + + //this is the API exposed by this directive, for either hosting controllers or for other directives + vm.callbacks = { + treeNodeExpanded: function (f) { + registeredCallbacks.treeNodeExpanded.push(f); + }, + treeNodeSelect: function (f) { + registeredCallbacks.treeNodeSelect.push(f); + }, + treeLoaded: function (f) { + registeredCallbacks.treeLoaded.push(f); + }, + treeSynced: function (f) { + registeredCallbacks.treeSynced.push(f); + }, + treeOptionsClick: function (f) { + registeredCallbacks.treeOptionsClick.push(f); + }, + treeNodeAltSelect: function (f) { + registeredCallbacks.treeNodeAltSelect.push(f); + } + }; + vm.emitEvent = emitEvent; + vm.load = load; + vm.reloadNode = reloadNode; + vm.syncTree = syncTree; + + //wire up the exposed api object for hosting controllers + if ($scope.api) { + $scope.api.callbacks = vm.callbacks; + $scope.api.load = vm.load; + $scope.api.reloadNode = vm.reloadNode; + $scope.api.syncTree = vm.syncTree; + } + + //flag to track the last loaded section when the tree 'un-loads'. We use this to determine if we should + // re-load the tree again. For example, if we hover over 'content' the content tree is shown. Then we hover + // outside of the tree and the tree 'un-loads'. When we re-hover over 'content', we don't want to re-load the + // entire tree again since we already still have it in memory. Of course if the section is different we will + // reload it. This saves a lot on processing if someone is navigating in and out of the same section many times + // since it saves on data retreival and DOM processing. + var lastSection = ""; + + //flag to enable/disable delete animations + var deleteAnimations = false; - /** - Used to do the tree syncing. If the args.tree is not specified we are assuming it has been - specified previously using the _setActiveTreeType - */ - scope.eventhandler.syncTree = function (args) { - if (!args) { - throw "args cannot be null"; - } - if (!args.path) { - throw "args.path cannot be null"; - } + /** Helper function to emit tree events */ + function emitEvent(eventName, args) { + if (registeredCallbacks[eventName] && angular.isArray(registeredCallbacks[eventName])) { + _.each(registeredCallbacks[eventName], function (c) { + c(args);//call it + }); + } + } - var deferred = $q.defer(); + /** This will deleteAnimations to true after the current digest */ + function enableDeleteAnimations() { + //do timeout so that it re-enables them after this digest + $timeout(function () { + //enable delete animations + deleteAnimations = true; + }, 0, false); + } + + function clearCache(section) { + treeService.clearCache({ section: section }); + } + + function load(section) { + $scope.section = section; + return loadTree(); + } + + function reloadNode(node) { - //this is super complex but seems to be working in other places, here we're listening for our - // own events, once the tree is sycned we'll resolve our promise. - scope.eventhandler.one("treeSynced", function (e, syncArgs) { - deferred.resolve(syncArgs); - }); - - //this should normally be set unless it is being called from legacy - // code, so set the active tree type before proceeding. - if (args.tree) { - loadActiveTree(args.tree); - } - - if (angular.isString(args.path)) { - args.path = args.path.replace('"', '').split(','); - } - - //reset current node selection - //scope.currentNode = null; - - //Filter the path for root node ids (we don't want to pass in -1 or 'init') - - args.path = _.filter(args.path, function (item) { return (item !== "init" && item !== "-1"); }); - - //Once those are filtered we need to check if the current user has a special start node id, - // if they do, then we're going to trim the start of the array for anything found from that start node - // and previous so that the tree syncs properly. The tree syncs from the top down and if there are parts - // of the tree's path in there that don't actually exist in the dom/model then syncing will not work. - - userService.getCurrentUser().then(function (userData) { - - var startNodes = []; - for (var i = 0; i < userData.startContentIds; i++) { - startNodes.push(userData.startContentIds[i]); - } - for (var j = 0; j < userData.startMediaIds; j++) { - startNodes.push(userData.startMediaIds[j]); - } - - _.each(startNodes, function (i) { - var found = _.find(args.path, function (p) { - return String(p) === String(i); - }); - if (found) { - args.path = args.path.splice(_.indexOf(args.path, found)); - } - }); - - - loadPath(args.path, args.forceReload, args.activate); - - }); - - - - return deferred.promise; - }; - - /** - Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to - have to set an active tree and then sync, the new API does this in one method by using syncTree. - loadChildren is optional but if it is set, it will set the current active tree and load the root - node's children - this is synonymous with the legacy refreshTree method - again should not be used - and should only be used for the legacy code to work. - */ - scope.eventhandler._setActiveTreeType = function (treeAlias, loadChildren) { - loadActiveTree(treeAlias, loadChildren); - }; - } + if (!node) { + node = $scope.currentNode; } - - //helper to load a specific path on the active tree as soon as its ready - function loadPath(path, forceReload, activate) { - - if (scope.activeTree) { - syncTree(scope.activeTree, path, forceReload, activate); - } - else { - scope.eventhandler.one("activeTreeLoaded", function (e, args) { - syncTree(args.tree, path, forceReload, activate); - }); - } + if (node) { + return $scope.loadChildren(node, true); + } + + return $q.reject(); + } + + /** + * Used to do the tree syncing + * @param {any} args + * @returns a promise with an object containing 'node' and 'activate' + */ + function syncTree(args) { + if (!args) { + throw "args cannot be null"; + } + if (!args.path) { + throw "args.path cannot be null"; + } + if (!args.tree) { + throw "args.tree cannot be null"; } - - //given a tree alias, this will search the current section tree for the specified tree alias and - //set that to the activeTree - //NOTE: loadChildren is ONLY used for legacy purposes, do not use this when syncing the tree as it will cause problems - // since there will be double request and event handling operations. - function loadActiveTree(treeAlias, loadChildren) { - if (!treeAlias) { - return; + //this should normally be set unless it is being called from legacy + // code, so set the active tree type before proceeding. + if (args.tree) { + var treeNode = getTreeRootNode(args.tree); + + if (angular.isString(args.path)) { + args.path = args.path.replace('"', '').split(','); } - scope.activeTree = undefined; + //Filter the path for root node ids (we don't want to pass in -1 or 'init') - function doLoad(tree) { - var childrenAndSelf = [tree].concat(tree.children); - scope.activeTree = _.find(childrenAndSelf, function (node) { - if (node && node.metaData && node.metaData.treeAlias) { - return node.metaData.treeAlias.toUpperCase() === treeAlias.toUpperCase(); - } - return false; - }); + args.path = _.filter(args.path, function (item) { return (item !== "init" && item !== "-1"); }); - if (!scope.activeTree) { - throw "Could not find the tree " + treeAlias + ", activeTree has not been set"; + //Once those are filtered we need to check if the current user has a special start node id, + // if they do, then we're going to trim the start of the array for anything found from that start node + // and previous so that the tree syncs properly. The tree syncs from the top down and if there are parts + // of the tree's path in there that don't actually exist in the dom/model then syncing will not work. + + return userService.getCurrentUser().then(function (userData) { + + var startNodes = []; + for (var i = 0; i < userData.startContentIds; i++) { + startNodes.push(userData.startContentIds[i]); + } + for (var j = 0; j < userData.startMediaIds; j++) { + startNodes.push(userData.startMediaIds[j]); } - //This is only used for the legacy tree method refreshTree! - if (loadChildren) { - scope.activeTree.expanded = true; - scope.loadChildren(scope.activeTree, false).then(function () { - emitEvent("activeTreeLoaded", { tree: scope.activeTree }); + _.each(startNodes, function (i) { + var found = _.find(args.path, function (p) { + return String(p) === String(i); }); - } - else { - emitEvent("activeTreeLoaded", { tree: scope.activeTree }); - } - } - - if (scope.tree) { - doLoad(scope.tree.root); - } - else { - scope.eventhandler.one("treeLoaded", function (e, args) { - doLoad(args.tree.root); + if (found) { + args.path = args.path.splice(_.indexOf(args.path, found)); + } }); - } - } - - - /** Method to load in the tree data */ - - function loadTree() { - if (!scope.loading && scope.section) { - scope.loading = true; - - //anytime we want to load the tree we need to disable the delete animations + deleteAnimations = false; - //default args - var args = { section: scope.section, tree: scope.treealias, cacheKey: scope.cachekey, isDialog: scope.isdialog ? scope.isdialog : false, onlyinitialized: scope.onlyinitialized }; + return treeService.syncTree({ + node: treeNode, + path: args.path, + forceReload: args.forceReload + }).then(function (data) { - //add the extra query string params if specified - if (scope.customtreeparams) { - args["queryString"] = scope.customtreeparams; - } + if (args.activate === undefined || args.activate === true) { + $scope.currentNode = data; + } - return treeService.getTree(args) - .then(function (data) { - //set the data once we have it - scope.tree = data; + emitEvent("treeSynced", { node: data, activate: args.activate }); - enableDeleteAnimations(); + enableDeleteAnimations(); + + return $q.when({ node: data, activate: args.activate }); + }); + }); + } + + } - scope.loading = false; + //given a tree alias, this will search the current section tree for the specified tree alias return it's root node + function getTreeRootNode(treeAlias) { + if (!treeAlias) { + throw "Err in umbtree.directive.loadActiveTree, treeAlias is null"; + } + if (!$scope.tree) { + throw "Err in umbtree.directive.loadActiveTree, $scope.tree is null"; + } - //set the root as the current active tree - scope.activeTree = scope.tree.root; - emitEvent("treeLoaded", { tree: scope.tree }); - emitEvent("treeNodeExpanded", { tree: scope.tree, node: scope.tree.root, children: scope.tree.root.children }); - return $q.when(data); - }, function (reason) { - scope.loading = false; - notificationsService.error("Tree Error", reason); - return $q.reject(reason); - }); - } - else { - return $q.reject(); + var childrenAndSelf = [$scope.tree.root].concat($scope.tree.root.children); + var found = _.find(childrenAndSelf, function (node) { + if (node && node.metaData && node.metaData.treeAlias) { + return node.metaData.treeAlias.toUpperCase() === treeAlias.toUpperCase(); } + return false; + }); + + if (!found) { + throw "Could not find the tree " + treeAlias; } - /** syncs the tree, the treeNode can be ANY tree node in the tree that requires syncing */ - function syncTree(treeNode, path, forceReload, activate) { + emitEvent("activeTreeLoaded", { tree: found }); + + return found; + } + /** Method to load in the tree data */ + + function loadTree() { + if (!$scope.loading && $scope.section) { + $scope.loading = true; + + //anytime we want to load the tree we need to disable the delete animations deleteAnimations = false; - treeService.syncTree({ - node: treeNode, - path: path, - forceReload: forceReload - }).then(function (data) { + //default args + var args = { section: $scope.section, tree: $scope.treealias, cacheKey: $scope.cachekey, isDialog: $scope.isdialog ? $scope.isdialog : false, onlyinitialized: $scope.onlyinitialized }; - if (activate === undefined || activate === true) { - scope.currentNode = data; - } + //add the extra query string params if specified + if ($scope.customtreeparams) { + args["queryString"] = $scope.customtreeparams; + } - emitEvent("treeSynced", { node: data, activate: activate }); + return treeService.getTree(args) + .then(function (data) { + //set the data once we have it + $scope.tree = data; - enableDeleteAnimations(); - }); + enableDeleteAnimations(); + $scope.loading = false; + + emitEvent("treeLoaded", { tree: $scope.tree }); + emitEvent("treeNodeExpanded", { tree: $scope.tree, node: $scope.tree.root, children: $scope.tree.root.children }); + return $q.when(data); + }, function (reason) { + $scope.loading = false; + notificationsService.error("Tree Error", reason); + return $q.reject(reason); + }); + } + else { + return $q.reject(); + } + } + + /** Returns the css classses assigned to the node (div element) */ + $scope.getNodeCssClass = function (node) { + if (!node) { + return ''; } - /** Returns the css classses assigned to the node (div element) */ - scope.getNodeCssClass = function (node) { - if (!node) { - return ''; - } + //TODO: This is called constantly because as a method in a template it's re-evaluated pretty much all the time + // it would be better if we could cache the processing. The problem is that some of these things are dynamic. - //TODO: This is called constantly because as a method in a template it's re-evaluated pretty much all the time - // it would be better if we could cache the processing. The problem is that some of these things are dynamic. + var css = []; + if (node.cssClasses) { + _.each(node.cssClasses, function (c) { + css.push(c); + }); + } - var css = []; - if (node.cssClasses) { - _.each(node.cssClasses, function (c) { - css.push(c); - }); - } - - return css.join(" "); - }; - - scope.selectEnabledNodeClass = function (node) { - return node ? - node.selected ? - 'icon umb-tree-icon sprTree icon-check green temporary' : - '' : - ''; - }; - - /** method to set the current animation for the node. - * This changes dynamically based on if we are changing sections or just loading normal tree data. - * When changing sections we don't want all of the tree-ndoes to do their 'leave' animations. - */ - scope.animation = function () { - if (deleteAnimations && scope.tree && scope.tree.root && scope.tree.root.expanded) { - return { leave: 'tree-node-delete-leave' }; - } - else { - return {}; - } - }; - - /* helper to force reloading children of a tree node */ - scope.loadChildren = function (node, forceReload) { - var deferred = $q.defer(); - - //emit treeNodeExpanding event, if a callback object is set on the tree - emitEvent("treeNodeExpanding", { tree: scope.tree, node: node }); - - //standardising - if (!node.children) { - node.children = []; - } - - if (forceReload || (node.hasChildren && node.children.length === 0)) { - //get the children from the tree service - treeService.loadNodeChildren({ node: node, section: scope.section }) - .then(function (data) { - //emit expanded event - emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: data }); - - enableDeleteAnimations(); - - deferred.resolve(data); - }); - } - else { - emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: node.children }); - node.expanded = true; - - enableDeleteAnimations(); - - deferred.resolve(node.children); - } - - return deferred.promise; - }; - - /** - Method called when the options button next to the root node is called. - The tree doesnt know about this, so it raises an event to tell the parent controller - about it. - */ - scope.options = function (n, ev) { - emitEvent("treeOptionsClick", { element: elem, node: n, event: ev }); - }; - - /** - Method called when an item is clicked in the tree, this passes the - DOM element, the tree node object and the original click - and emits it as a treeNodeSelect element if there is a callback object - defined on the tree - */ - scope.select = function (n, ev) { - - if (n.metaData && n.metaData.noAccess === true) { - ev.preventDefault(); - return; - } - - //on tree select we need to remove the current node - - // whoever handles this will need to make sure the correct node is selected - //reset current node selection - scope.currentNode = null; - - emitEvent("treeNodeSelect", { element: elem, node: n, event: ev }); - }; - - scope.altSelect = function (n, ev) { - emitEvent("treeNodeAltSelect", { element: elem, tree: scope.tree, node: n, event: ev }); - }; - - //watch for section changes - scope.$watch("section", function (newVal, oldVal) { - - if (!scope.tree) { - loadTree(); - } - - if (!newVal) { - //store the last section loaded - lastSection = oldVal; - } - else if (newVal !== oldVal && newVal !== lastSection) { - //only reload the tree data and Dom if the newval is different from the old one - // and if the last section loaded is different from the requested one. - loadTree(); - - //store the new section to be loaded as the last section - //clear any active trees to reset lookups - lastSection = newVal; - } - }); - - setupExternalEvents(); - loadTree(); + return css.join(" "); }; + + $scope.selectEnabledNodeClass = function (node) { + return node ? + node.selected ? + 'icon umb-tree-icon sprTree icon-check green temporary' : + '' : + ''; + }; + + /** method to set the current animation for the node. + * This changes dynamically based on if we are changing sections or just loading normal tree data. + * When changing sections we don't want all of the tree-ndoes to do their 'leave' animations. + */ + $scope.animation = function () { + if (deleteAnimations && $scope.tree && $scope.tree.root && $scope.tree.root.expanded) { + return { leave: 'tree-node-delete-leave' }; + } + else { + return {}; + } + }; + + /* helper to force reloading children of a tree node */ + $scope.loadChildren = function (node, forceReload) { + + //emit treeNodeExpanding event, if a callback object is set on the tree + emitEvent("treeNodeExpanding", { tree: $scope.tree, node: node }); + + //standardising + if (!node.children) { + node.children = []; + } + + if (forceReload || (node.hasChildren && node.children.length === 0)) { + //get the children from the tree service + return treeService.loadNodeChildren({ node: node, section: $scope.section }) + .then(function (data) { + //emit expanded event + emitEvent("treeNodeExpanded", { tree: $scope.tree, node: node, children: data }); + + enableDeleteAnimations(); + + return $q.when(data); + }); + } + else { + emitEvent("treeNodeExpanded", { tree: $scope.tree, node: node, children: node.children }); + node.expanded = true; + + enableDeleteAnimations(); + + return $q.when(node.children); + } + }; + + /** + Method called when the options button next to the root node is called. + The tree doesnt know about this, so it raises an event to tell the parent controller + about it. + */ + $scope.options = function (n, ev) { + emitEvent("treeOptionsClick", { element: elem, node: n, event: ev }); + }; + + /** + Method called when an item is clicked in the tree, this passes the + DOM element, the tree node object and the original click + and emits it as a treeNodeSelect element if there is a callback object + defined on the tree + */ + $scope.select = function (n, ev) { + + if (n.metaData && n.metaData.noAccess === true) { + ev.preventDefault(); + return; + } + + //on tree select we need to remove the current node - + // whoever handles this will need to make sure the correct node is selected + //reset current node selection + $scope.currentNode = null; + + emitEvent("treeNodeSelect", { element: elem, node: n, event: ev }); + }; + + $scope.altSelect = function (n, ev) { + emitEvent("treeNodeAltSelect", { element: elem, tree: $scope.tree, node: n, event: ev }); + }; + + //watch for section changes + $scope.$watch("section", function (newVal, oldVal) { + + if (!$scope.tree) { + loadTree(); + } + + if (!newVal) { + //store the last section loaded + lastSection = oldVal; + } + else if (newVal !== oldVal && newVal !== lastSection) { + //only reload the tree data and Dom if the newval is different from the old one + // and if the last section loaded is different from the requested one. + loadTree(); + + //store the new section to be loaded as the last section + //clear any active trees to reset lookups + lastSection = newVal; + } + }); + + //call the callback, this allows for hosting controllers to bind to events and use the exposed API + $scope.onInit(); + + loadTree(); } }; } diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js index 0bb888a59f..5e2f53bc44 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtreeitem.directive.js @@ -22,14 +22,13 @@ angular.module("umbraco.directives") return { restrict: 'E', replace: true, - + require: '^umbTree', scope: { section: '@', - eventhandler: '=', currentNode: '=', enablelistviewexpand: '@', node: '=', - tree: '=' + tree: '=' //TODO: Not sure we need this since we are 'require' on the umbTree }, //TODO: Remove more of the binding from this template and move the DOM manipulation to be manually done in the link function, @@ -48,7 +47,7 @@ angular.module("umbraco.directives") '' + '', - link: function (scope, element, attrs) { + link: function (scope, element, attrs, umbTreeCtrl) { localizationService.localize("general_search").then(function (value) { scope.searchAltText = value; @@ -57,14 +56,6 @@ angular.module("umbraco.directives") //flag to enable/disable delete animations, default for an item is true var deleteAnimations = true; - // Helper function to emit tree events - function emitEvent(eventName, args) { - - if (scope.eventhandler) { - $(scope.eventhandler).trigger(eventName, args); - } - } - // updates the node's DOM/styles function setupNodeDom(node, tree) { @@ -153,7 +144,7 @@ angular.module("umbraco.directives") about it. */ scope.options = function (n, ev) { - emitEvent("treeOptionsClick", { element: element, tree: scope.tree, node: n, event: ev }); + umbTreeCtrl.emitEvent("treeOptionsClick", { element: element, tree: scope.tree, node: n, event: ev }); }; /** @@ -176,7 +167,7 @@ angular.module("umbraco.directives") return; } - emitEvent("treeNodeSelect", { element: element, tree: scope.tree, node: n, event: ev }); + umbTreeCtrl.emitEvent("treeNodeSelect", { element: element, tree: scope.tree, node: n, event: ev }); ev.preventDefault(); }; @@ -187,7 +178,7 @@ angular.module("umbraco.directives") defined on the tree */ scope.altSelect = function (n, ev) { - emitEvent("treeNodeAltSelect", { element: element, tree: scope.tree, node: n, event: ev }); + umbTreeCtrl.emitEvent("treeNodeAltSelect", { element: element, tree: scope.tree, node: n, event: ev }); }; /** method to set the current animation for the node. @@ -214,7 +205,7 @@ angular.module("umbraco.directives") scope.load = function (node) { if (node.expanded && !node.metaData.isContainer) { deleteAnimations = false; - emitEvent("treeNodeCollapsing", { tree: scope.tree, node: node, element: element }); + umbTreeCtrl.emitEvent("treeNodeCollapsing", { tree: scope.tree, node: node, element: element }); node.expanded = false; } else { @@ -225,19 +216,19 @@ angular.module("umbraco.directives") /* helper to force reloading children of a tree node */ scope.loadChildren = function (node, forceReload) { //emit treeNodeExpanding event, if a callback object is set on the tree - emitEvent("treeNodeExpanding", { tree: scope.tree, node: node }); + umbTreeCtrl.emitEvent("treeNodeExpanding", { tree: scope.tree, node: node }); if (node.hasChildren && (forceReload || !node.children || (angular.isArray(node.children) && node.children.length === 0))) { //get the children from the tree service treeService.loadNodeChildren({ node: node, section: scope.section }) .then(function (data) { //emit expanded event - emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: data }); + umbTreeCtrl.emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: data }); enableDeleteAnimations(); }); } else { - emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: node.children }); + umbTreeCtrl.emitEvent("treeNodeExpanded", { tree: scope.tree, node: node, children: node.children }); node.expanded = true; enableDeleteAnimations(); } @@ -253,11 +244,14 @@ angular.module("umbraco.directives") scope.loadChildren(scope.node); } - var template = ''; + var template = ''; var newElement = angular.element(template); $compile(newElement)(scope); element.append(newElement); + }, + controller: function ($scope) { + } }; }); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/events.service.js b/src/Umbraco.Web.UI.Client/src/common/services/events.service.js index e28970336f..74b9abdb6a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/events.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/events.service.js @@ -9,7 +9,8 @@ app.closeDialogs app.ysod app.reInitialize - app.userRefresh + app.userRefresh + app.navigationReady */ function eventsService($q, $rootScope) { @@ -42,4 +43,4 @@ function eventsService($q, $rootScope) { }; } -angular.module('umbraco.services').factory('eventsService', eventsService); \ No newline at end of file +angular.module('umbraco.services').factory('eventsService', eventsService); diff --git a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js index d3250ee64b..0adfc3b3e1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/navigation.service.js @@ -15,14 +15,18 @@ * Section navigation and search, and maintain their state for the entire application lifetime * */ -function navigationService($rootScope, $routeParams, $log, $location, $q, $timeout, $injector, dialogService, umbModelMapper, treeService, notificationsService, historyService, appState, angularHelper) { +function navigationService($rootScope, $routeParams, $log, $location, $q, $timeout, $injector, eventsService, dialogService, umbModelMapper, treeService, notificationsService, historyService, appState, angularHelper) { + //the main tree's API reference, this is acquired when the tree has initialized + var mainTreeApi = null; + + eventsService.on("app.navigationReady", function (e, args) { + mainTreeApi = args.treeApi; + }); //used to track the current dialog object var currentDialog = null; - - //the main tree event handler, which gets assigned via the setupTreeEvents method - var mainTreeEventHandler = null; + //tracks the user profile dialog var userDialog = null; @@ -165,100 +169,6 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo appState.setGlobalState("showTray", false); }, - /** - Called to assign the main tree event handler - this is called by the navigation controller. - TODO: Potentially another dev could call this which would kind of mung the whole app so potentially there's a better way. - */ - setupTreeEvents: function(treeEventHandler) { - mainTreeEventHandler = treeEventHandler; - - //when a tree is loaded into a section, we need to put it into appState - mainTreeEventHandler.bind("treeLoaded", function(ev, args) { - appState.setTreeState("currentRootNode", args.tree); - }); - - //when a tree node is synced this event will fire, this allows us to set the currentNode - mainTreeEventHandler.bind("treeSynced", function (ev, args) { - - if (args.activate === undefined || args.activate === true) { - //set the current selected node - appState.setTreeState("selectedNode", args.node); - //when a node is activated, this is the same as clicking it and we need to set the - //current menu item to be this node as well. - appState.setMenuState("currentNode", args.node); - } - }); - - //this reacts to the options item in the tree - mainTreeEventHandler.bind("treeOptionsClick", function(ev, args) { - ev.stopPropagation(); - ev.preventDefault(); - - //Set the current action node (this is not the same as the current selected node!) - appState.setMenuState("currentNode", args.node); - - if (args.event && args.event.altKey) { - args.skipDefault = true; - } - - service.showMenu(ev, args); - }); - - mainTreeEventHandler.bind("treeNodeAltSelect", function(ev, args) { - ev.stopPropagation(); - ev.preventDefault(); - - args.skipDefault = true; - service.showMenu(ev, args); - }); - - //this reacts to tree items themselves being clicked - //the tree directive should not contain any handling, simply just bubble events - mainTreeEventHandler.bind("treeNodeSelect", function (ev, args) { - var n = args.node; - ev.stopPropagation(); - ev.preventDefault(); - - if (n.metaData && n.metaData["jsClickCallback"] && angular.isString(n.metaData["jsClickCallback"]) && n.metaData["jsClickCallback"] !== "") { - //this is a legacy tree node! - var jsPrefix = "javascript:"; - var js; - if (n.metaData["jsClickCallback"].startsWith(jsPrefix)) { - js = n.metaData["jsClickCallback"].substr(jsPrefix.length); - } - else { - js = n.metaData["jsClickCallback"]; - } - try { - var func = eval(js); - //this is normally not necessary since the eval above should execute the method and will return nothing. - if (func != null && (typeof func === "function")) { - func.call(); - } - } - catch(ex) { - $log.error("Error evaluating js callback from legacy tree node: " + ex); - } - } - else if (n.routePath) { - //add action to the history service - historyService.add({ name: n.name, link: n.routePath, icon: n.icon }); - - //put this node into the tree state - appState.setTreeState("selectedNode", args.node); - //when a node is clicked we also need to set the active menu node to this node - appState.setMenuState("currentNode", args.node); - - //not legacy, lets just set the route value and clear the query string if there is one. - $location.path(n.routePath).search(""); - } - else if (args.element.section) { - $location.path(args.element.section).search(""); - } - - service.hideNavigation(); - }); - }, /** * @ngdoc method * @name umbraco.services.navigationService#syncTree @@ -288,12 +198,9 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo throw "args.tree cannot be null"; } - if (mainTreeEventHandler) { - - if (mainTreeEventHandler.syncTree) { - //returns a promise, - return mainTreeEventHandler.syncTree(args); - } + if (mainTreeApi) { + //returns a promise, + return mainTreeApi.syncTree(args); } //couldn't sync @@ -305,33 +212,23 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo have to set an active tree and then sync, the new API does this in one method by using syncTree */ _syncPath: function(path, forceReload) { - if (mainTreeEventHandler) { - mainTreeEventHandler.syncTree({ path: path, forceReload: forceReload }); + if (mainTreeApi) { + mainTreeApi.syncTree({ path: path, forceReload: forceReload }); } }, //TODO: This should return a promise reloadNode: function(node) { - if (mainTreeEventHandler) { - mainTreeEventHandler.reloadNode(node); + if (mainTreeApi) { + mainTreeApi.reloadNode(node); } }, //TODO: This should return a promise reloadSection: function(sectionAlias) { - if (mainTreeEventHandler) { - mainTreeEventHandler.clearCache({ section: sectionAlias }); - mainTreeEventHandler.load(sectionAlias); - } - }, - - /** - Internal method that should ONLY be used by the legacy API wrapper, the legacy API used to - have to set an active tree and then sync, the new API does this in one method by using syncTreePath - */ - _setActiveTreeType: function (treeAlias, loadChildren) { - if (mainTreeEventHandler) { - mainTreeEventHandler._setActiveTreeType(treeAlias, loadChildren); + if (mainTreeApi) { + mainTreeApi.clearCache({ section: sectionAlias }); + mainTreeApi.load(sectionAlias); } }, @@ -364,7 +261,7 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * * @param {Event} event the click event triggering the method, passed from the DOM element */ - showMenu: function(event, args) { + showMenu: function(args) { var deferred = $q.defer(); var self = this; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js index 80565c23e3..316a75117b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js @@ -247,10 +247,9 @@ angular.module('umbraco.services') /** Returns the current user object in a promise */ getCurrentUser: function (args) { - var deferred = $q.defer(); - + if (!currentUser) { - authResource.getCurrentUser() + return authResource.getCurrentUser() .then(function (data) { var result = { user: data, authenticated: true, lastUserId: lastUserId, loginType: "implicit" }; @@ -261,19 +260,17 @@ angular.module('umbraco.services') } setCurrentUser(data); - - deferred.resolve(currentUser); + + return $q.when(currentUser); }, function () { - //it failed, so they are not logged in - deferred.reject(); + //it failed, so they are not logged in + return $q.reject(currentUser); }); } else { - deferred.resolve(currentUser); + return $q.when(currentUser); } - - return deferred.promise; }, /** Loads the Moment.js Locale for the current user. */ @@ -295,11 +292,7 @@ angular.module('umbraco.services') return assetsService.load(localeUrls, $rootScope); } else { - //return a noop promise - var deferred = $q.defer(); - var promise = deferred.promise; - deferred.resolve(true); - return promise; + $q.when(true); } } diff --git a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js index 377424f3d4..b4a1f284d5 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js @@ -14,6 +14,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ $scope.authenticated = null; $scope.touchDevice = appState.getGlobalState("touchDevice"); $scope.overlay = {}; + $scope.navReady = false; $scope.removeNotification = function (index) { @@ -60,6 +61,10 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ }); })); + evts.push(eventsService.on('app.navigationReady', function () { + $scope.navReady = true; + })); + //when the app is ready/user is logged in, setup the data evts.push(eventsService.on("app.ready", function (evt, data) { diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index 6330f5a30a..1cb2760ec2 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -11,10 +11,100 @@ */ function NavigationController($scope, $rootScope, $location, $log, $routeParams, $timeout, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper, languageResource) { - //TODO: Need to think about this and an nicer way to acheive what this is doing. - //the tree event handler i used to subscribe to the main tree click events - $scope.treeEventHandler = $({}); - navigationService.setupTreeEvents($scope.treeEventHandler); + $scope.treeApi = {}; + + //Bind to the main tree events + $scope.onTreeInit = function () { + //when a tree is loaded into a section, we need to put it into appState + $scope.treeApi.callbacks.treeLoaded(function (args) { + appState.setTreeState("currentRootNode", args.tree); + }); + + //when a tree node is synced this event will fire, this allows us to set the currentNode + $scope.treeApi.callbacks.treeSynced(function (args) { + + if (args.activate === undefined || args.activate === true) { + //set the current selected node + appState.setTreeState("selectedNode", args.node); + //when a node is activated, this is the same as clicking it and we need to set the + //current menu item to be this node as well. + appState.setMenuState("currentNode", args.node); + } + }); + + //this reacts to the options item in the tree + $scope.treeApi.callbacks.treeOptionsClick(function (args) { + args.event.stopPropagation(); + args.event.preventDefault(); + + //Set the current action node (this is not the same as the current selected node!) + appState.setMenuState("currentNode", args.node); + + if (args.event && args.event.altKey) { + args.skipDefault = true; + } + + navigationService.showMenu(args); + }); + + $scope.treeApi.callbacks.treeNodeAltSelect(function (args) { + args.event.stopPropagation(); + args.event.preventDefault(); + + args.skipDefault = true; + navigationService.showMenu(args); + }); + + //this reacts to tree items themselves being clicked + //the tree directive should not contain any handling, simply just bubble events + $scope.treeApi.callbacks.treeNodeSelect(function (args) { + var n = args.node; + args.event.stopPropagation(); + args.event.preventDefault(); + + if (n.metaData && n.metaData["jsClickCallback"] && angular.isString(n.metaData["jsClickCallback"]) && n.metaData["jsClickCallback"] !== "") { + //this is a legacy tree node! + var jsPrefix = "javascript:"; + var js; + if (n.metaData["jsClickCallback"].startsWith(jsPrefix)) { + js = n.metaData["jsClickCallback"].substr(jsPrefix.length); + } + else { + js = n.metaData["jsClickCallback"]; + } + try { + var func = eval(js); + //this is normally not necessary since the eval above should execute the method and will return nothing. + if (func != null && (typeof func === "function")) { + func.call(); + } + } + catch (ex) { + $log.error("Error evaluating js callback from legacy tree node: " + ex); + } + } + else if (n.routePath) { + //add action to the history service + historyService.add({ name: n.name, link: n.routePath, icon: n.icon }); + + //put this node into the tree state + appState.setTreeState("selectedNode", args.node); + //when a node is clicked we also need to set the active menu node to this node + appState.setMenuState("currentNode", args.node); + + //not legacy, lets just set the route value and clear the query string if there is one. + $location.path(n.routePath).search(""); + } + else if (args.element.section) { + $location.path(args.element.section).search(""); + } + + navigationService.hideNavigation(); + }); + + //once this is wired up, the nav is ready + eventsService.emit("app.navigationReady", { treeApi: $scope.treeApi}); + } //Put the navigation service on this scope so we can use it's methods/properties in the view. // IMPORTANT: all properties assigned to this scope are generally available on the scope object on dialogs since @@ -155,14 +245,16 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, }; //this reacts to the options item in the tree - //todo, migrate to nav service + //TODO: migrate to nav service + //TODO: is this used? $scope.searchShowMenu = function (ev, args) { //always skip default args.skipDefault = true; - navigationService.showMenu(ev, args); + navigationService.showMenu(args); }; - //todo, migrate to nav service + //TODO: migrate to nav service + //TODO: is this used? $scope.searchHide = function () { navigationService.hideSearch(); }; diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index 32462826fe..666fcfdf5d 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -1,42 +1,43 @@ /** Executed when the application starts, binds to events and set global state */ -app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navigationService', 'appState', 'editorState', 'fileManager', 'assetsService', 'eventsService', '$cookies', '$templateCache', 'localStorageService', 'tourService', 'dashboardResource', - function (userService, $log, $rootScope, $location, queryStrings, navigationService, appState, editorState, fileManager, assetsService, eventsService, $cookies, $templateCache, localStorageService, tourService, dashboardResource) { - +app.run(['userService', '$q', '$log', '$rootScope', '$location', 'queryStrings', 'navigationService', 'appState', 'editorState', 'fileManager', 'assetsService', 'eventsService', '$cookies', '$templateCache', 'localStorageService', 'tourService', 'dashboardResource', + function (userService, $q, $log, $rootScope, $location, queryStrings, navigationService, appState, editorState, fileManager, assetsService, eventsService, $cookies, $templateCache, localStorageService, tourService, dashboardResource) { + //This sets the default jquery ajax headers to include our csrf token, we // need to user the beforeSend method because our token changes per user/login so // it cannot be static $.ajaxSetup({ beforeSend: function (xhr) { xhr.setRequestHeader("X-UMB-XSRF-TOKEN", $cookies["UMB-XSRF-TOKEN"]); - if (queryStrings.getParams().umbDebug === "true" || queryStrings.getParams().umbdebug === "true") { - xhr.setRequestHeader("X-UMB-DEBUG", "true"); - } + if (queryStrings.getParams().umbDebug === "true" || queryStrings.getParams().umbdebug === "true") { + xhr.setRequestHeader("X-UMB-DEBUG", "true"); + } } }); /** Listens for authentication and checks if our required assets are loaded, if/once they are we'll broadcast a ready event */ - eventsService.on("app.authenticated", function(evt, data) { + eventsService.on("app.authenticated", function (evt, data) { - assetsService._loadInitAssets().then(function() { + $q.all([ + assetsService._loadInitAssets(), + userService.loadMomentLocaleForCurrentUser(), + tourService.registerAllTours() + ]).then(function () { - // Loads the user's locale settings for Moment. - userService.loadMomentLocaleForCurrentUser().then(function() { + //Register all of the tours on the server + tourService.registerAllTours().then(function () { + appReady(data); - //Register all of the tours on the server - tourService.registerAllTours().then(function () { - appReady(data); - - // Auto start intro tour - tourService.getTourByAlias("umbIntroIntroduction").then(function (introTour) { - // start intro tour if it hasn't been completed or disabled - if (introTour && introTour.disabled !== true && introTour.completed !== true) { - tourService.startTour(introTour); - } - }); - - }, function(){ - appReady(data); + // Auto start intro tour + tourService.getTourByAlias("umbIntroIntroduction").then(function (introTour) { + // start intro tour if it hasn't been completed or disabled + if (introTour && introTour.disabled !== true && introTour.completed !== true) { + tourService.startTour(introTour); + } }); + + }, function () { + appAuthenticated = true; + appReady(data); }); }); @@ -50,7 +51,7 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi } /** execute code on each successful route */ - $rootScope.$on('$routeChangeSuccess', function(event, current, previous) { + $rootScope.$on('$routeChangeSuccess', function (event, current, previous) { var deployConfig = Umbraco.Sys.ServerVariables.deploy; var deployEnv, deployEnvTitle; @@ -59,7 +60,7 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi deployEnvTitle = "(" + deployEnv + ") "; } - if(current.params.section) { + if (current.params.section) { //Uppercase the current section, content, media, settings, developer, forms var currentSection = current.params.section.charAt(0).toUpperCase() + current.params.section.slice(1); @@ -67,18 +68,18 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi var baseTitle = currentSection + " - " + $location.$$host; //Check deploy for Global Umbraco.Sys obj workspace - if(deployEnv){ + if (deployEnv) { $rootScope.locationTitle = deployEnvTitle + baseTitle; } else { $rootScope.locationTitle = baseTitle; } - + } else { - if(deployEnv) { - $rootScope.locationTitle = deployEnvTitle + "Umbraco - " + $location.$$host; + if (deployEnv) { + $rootScope.locationTitle = deployEnvTitle + "Umbraco - " + $location.$$host; } $rootScope.locationTitle = "Umbraco - " + $location.$$host; @@ -95,7 +96,7 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi /** When the route change is rejected - based on checkAuth - we'll prevent the rejected route from executing including wiring up it's controller, etc... and then redirect to the rejected URL. */ - $rootScope.$on('$routeChangeError', function(event, current, previous, rejection) { + $rootScope.$on('$routeChangeError', function (event, current, previous, rejection) { event.preventDefault(); var returnPath = null; @@ -111,13 +112,12 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi }); - /* this will initialize the navigation service once the application has started */ navigationService.init(); //check for touch device, add to global appState //var touchDevice = ("ontouchstart" in window || window.touch || window.navigator.msMaxTouchPoints === 5 || window.DocumentTouch && document instanceof DocumentTouch); - var touchDevice = /android|webos|iphone|ipad|ipod|blackberry|iemobile|touch/i.test(navigator.userAgent.toLowerCase()); + var touchDevice = /android|webos|iphone|ipad|ipod|blackberry|iemobile|touch/i.test(navigator.userAgent.toLowerCase()); appState.setGlobalState("touchDevice", touchDevice); }]); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.controller.js index e76db90f47..5055f088c7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.controller.js @@ -8,7 +8,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController", searchText = value + "..."; }); - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.target = {}; $scope.searchInfo = { searchFromId: null, @@ -30,7 +30,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController", entityResource.getPath(id, "Document").then(function (path) { $scope.target.path = path; //now sync the tree to this path - $scope.dialogTreeEventHandler.syncTree({ path: $scope.target.path, tree: "content" }); + $scope.dialogTreeApi.syncTree({ path: $scope.target.path, tree: "content" }); }); } @@ -40,7 +40,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController", } } - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -80,7 +80,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController", } } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { if (angular.isArray(args.children)) { //iterate children @@ -138,12 +138,10 @@ angular.module("umbraco").controller("Umbraco.Dialogs.LinkPickerController", $scope.searchInfo.results = results; $scope.searchInfo.showSearch = true; }; - - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); - }); \ No newline at end of file + + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.html index 442357edcc..5d1bbd8f80 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/linkpicker.html @@ -46,7 +46,8 @@ diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js index 93de97a8ea..8962bf91a3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.controller.js @@ -2,7 +2,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.MemberGroupPickerController", function($scope, eventsService, entityResource, searchService, $log) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.multiPicker = dialogOptions.multiPicker; /** Method used for selecting a node */ @@ -16,7 +16,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.MemberGroupPickerControlle } } - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -29,10 +29,9 @@ angular.module("umbraco").controller("Umbraco.Dialogs.MemberGroupPickerControlle //toggle checked state args.node.selected = args.node.selected === true ? false : true; } + + function onTreeInit() { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); - }); \ No newline at end of file + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html index e2ff9790d5..23b8bb93e0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/membergrouppicker.html @@ -7,8 +7,9 @@ treealias="memberGroups" hideheader="true" hideoptions="true" - isdialog="true" - eventhandler="dialogTreeEventHandler" + isdialog="true" + on-init="onTreeInit()" + api="dialogTreeApi" enablecheckboxes="{{multiPicker}}"> @@ -31,4 +32,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js index 740791abf9..e6d0da2b6f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.controller.js @@ -4,7 +4,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController", var tree = null; var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.section = dialogOptions.section; $scope.treeAlias = dialogOptions.treeAlias; $scope.multiPicker = dialogOptions.multiPicker; @@ -138,7 +138,7 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController", } //gets the tree object when it loads - function treeLoadedHandler(ev, args) { + function treeLoadedHandler(args) { tree = args.tree; } @@ -418,14 +418,11 @@ angular.module("umbraco").controller("Umbraco.Dialogs.TreePickerController", $scope.searchInfo.showSearch = true; }; + + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeLoaded(treeLoadedHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } - $scope.dialogTreeEventHandler.bind("treeLoaded", treeLoadedHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeLoaded", treeLoadedHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); - }); \ No newline at end of file + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.html index 3d39817680..9d17148042 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/treepicker.html @@ -29,7 +29,8 @@ hideoptions="true" isdialog="true" customtreeparams="{{customTreeParams}}" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewsearch="true" enablecheckboxes="{{multiPicker}}"> diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.controller.js index df6b51bea0..47e078d33c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.controller.js @@ -22,7 +22,7 @@ }); $scope.model.relateToOriginal = true; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; vm.searchInfo = { searchFromId: null, @@ -35,7 +35,7 @@ // get entity type based on the section $scope.entityType = entityHelper.getEntityTypeFromSection(dialogOptions.section); - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { if(args && args.event) { args.event.preventDefault(); args.event.stopPropagation(); @@ -52,7 +52,7 @@ $scope.model.target.selected = true; } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { // open mini list view for list views if (args.node.metaData.isContainer) { openMiniListView(args.node); @@ -78,13 +78,11 @@ vm.searchInfo.showSearch = true; } - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + } - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); // Mini list view $scope.selectListViewNode = function (node) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.html index aeafaec04b..16d00c8689 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/copy/copy.html @@ -26,7 +26,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewexpand="true" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js index 91c74311b3..653403a0f5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.controller.js @@ -12,7 +12,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController", $scope.model.title = localizationService.localize("defaultdialogs_selectLink"); } - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.model.target = {}; $scope.searchInfo = { searchFromId: null, @@ -38,7 +38,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController", entityResource.getPath(id, "Document").then(function (path) { $scope.model.target.path = path; //now sync the tree to this path - $scope.dialogTreeEventHandler.syncTree({ path: $scope.model.target.path, tree: "content" }); + $scope.dialogTreeApi.syncTree({ path: $scope.model.target.path, tree: "content" }); }); } @@ -48,7 +48,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController", } } - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { if(args && args.event) { args.event.preventDefault(); @@ -82,7 +82,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController", } } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { // open mini list view for list views if (args.node.metaData.isContainer) { openMiniListView(args.node); @@ -131,14 +131,11 @@ angular.module("umbraco").controller("Umbraco.Overlays.LinkPickerController", $scope.searchInfo.showSearch = true; }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); - + $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; diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html index e1b13206df..a59207c46a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/linkpicker/linkpicker.html @@ -52,7 +52,8 @@ section="content" hideheader="true" hideoptions="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewexpand="true" isdialog="true" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.controller.js index e823b2cc44..d60f3c32f5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.controller.js @@ -6,7 +6,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.MemberGroupPickerControll $scope.model.title = localizationService.localize("defaultdialogs_selectMemberGroup"); } - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.multiPicker = $scope.model.multiPicker; function activate() { @@ -39,7 +39,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.MemberGroupPickerControll } } - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -52,13 +52,11 @@ angular.module("umbraco").controller("Umbraco.Overlays.MemberGroupPickerControll //toggle checked state args.node.selected = args.node.selected === true ? false : true; } - - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); - + + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + }; + activate(); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.html index 22fdeaf8be..a416abf64b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/membergrouppicker/membergrouppicker.html @@ -5,7 +5,8 @@ hideheader="true" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablecheckboxes="{{model.multiPicker}}"> diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.controller.js index 78b7c7be34..adf616a603 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.controller.js @@ -22,7 +22,7 @@ } $scope.model.relateToOriginal = true; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; vm.searchInfo = { searchFromId: null, @@ -35,7 +35,7 @@ // get entity type based on the section $scope.entityType = entityHelper.getEntityTypeFromSection(dialogOptions.section); - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { if(args && args.event) { args.event.preventDefault(); @@ -54,7 +54,7 @@ } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { // open mini list view for list views if (args.node.metaData.isContainer) { openMiniListView(args.node); @@ -80,13 +80,10 @@ vm.searchInfo.showSearch = true; } - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + } // Mini list view $scope.selectListViewNode = function (node) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.html index 34130c31a8..30afe56d4b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/move/move.html @@ -25,7 +25,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewexpand="true" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index cd5872f2ab..29b4710eea 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -27,8 +27,9 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", var expandedPaths = []; var vm = this; - vm.treeReady = false; - vm.dialogTreeEventHandler = $({}); + vm.treeReady = false; + vm.dialogTreeApi = {}; + vm.initDialogTree = initDialogTree; vm.section = $scope.model.section; vm.treeAlias = $scope.model.treeAlias; vm.multiPicker = $scope.model.multiPicker; @@ -63,11 +64,17 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", vm.closeMiniListView = closeMiniListView; vm.selectListViewNode = selectListViewNode; + function initDialogTree() { + vm.dialogTreeApi.callbacks.treeLoaded(treeLoadedHandler); + vm.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + vm.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } + /** * Performs the initialization of this component */ - function onInit () { - + function onInit () { + // load languages languageResource.getAll().then(function (languages) { vm.languages = languages; @@ -99,14 +106,8 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", $scope.model.title = localizationService.localize("defaultdialogs_selectMedia"); } } - - //var searchText = "Search..."; - //localizationService.localize("general_search").then(function (value) { - // searchText = value + "..."; - //}); - //min / max values - //TODO: Where are these used? + //TODO: Seems odd this logic is here, i don't think it needs to be and should just exist on the property editor using this if ($scope.model.minNumber) { $scope.model.minNumber = parseInt($scope.model.minNumber, 10); } @@ -196,7 +197,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", $timeout(function () { //execute in the next digest since the $watch needs to update first //reload the tree with it's updated querystring args - vm.dialogTreeEventHandler.load(vm.section).then(function () { + vm.dialogTreeApi.load(vm.section).then(function () { //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in //sequence but that's what we need to do here @@ -204,7 +205,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", //create the list of promises var promises = []; for (var i = 0; i < expandedPaths.length; i++) { - promises.push(vm.dialogTreeEventHandler.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + promises.push(vm.dialogTreeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); } //now execute them in sequence... sorry there's no other good way to do it with angular promises @@ -264,7 +265,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", }); } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { //store the reference to the expanded node path if (args.node) { @@ -299,7 +300,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", } //gets the tree object when it loads - function treeLoadedHandler(ev, args) { + function treeLoadedHandler(args) { //args.tree contains children (args.tree.root.children) vm.hasItems = args.tree.root.children.length > 0; @@ -307,7 +308,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", } //wires up selection - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -652,17 +653,6 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", function closeMiniListView() { vm.miniListView = undefined; } - - vm.dialogTreeEventHandler.bind("treeLoaded", treeLoadedHandler); - vm.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - vm.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', - function () { - vm.dialogTreeEventHandler.unbind("treeLoaded", treeLoadedHandler); - vm.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - vm.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); //initialize onInit(); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html index fd198bb0fb..1beffb585e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.html @@ -39,10 +39,11 @@ isdialog="true" onlyinitialized="{{vm.onlyInitialized}}" customtreeparams="{{vm.customTreeParams}}" - eventhandler="vm.dialogTreeEventHandler" enablelistviewsearch="true" enablelistviewexpand="true" - enablecheckboxes="{{vm.multiPicker}}"> + enablecheckboxes="{{vm.multiPicker}}" + on-init="vm.initDialogTree()" + api="vm.dialogTreeApi"> diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html index 5eee7cfec9..91f1231ae7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html @@ -19,7 +19,8 @@
@@ -49,4 +50,4 @@ - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.copy.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.copy.controller.js index fa2d831eac..e8b5bbf2c3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.copy.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.copy.controller.js @@ -9,7 +9,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.CopyController", $scope.relateToOriginal = true; $scope.recursive = true; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.busy = false; $scope.searchInfo = { searchFromId: null, @@ -27,7 +27,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.CopyController", var node = dialogOptions.currentNode; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { if(args && args.event) { args.event.preventDefault(); @@ -46,7 +46,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.CopyController", } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { // open mini list view for list views if (args.node.metaData.isContainer) { openMiniListView(args.node); @@ -110,13 +110,10 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.CopyController", }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + } // Mini list view $scope.selectListViewNode = function (node) { diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.move.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.move.controller.js index 984c147ee4..d978d1673c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.move.controller.js @@ -7,7 +7,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController", searchText = value + "..."; }); - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; $scope.busy = false; $scope.searchInfo = { searchFromId: null, @@ -25,7 +25,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController", var node = dialogOptions.currentNode; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { if(args && args.event) { args.event.preventDefault(); @@ -44,7 +44,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController", } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { // open mini list view for list views if (args.node.metaData.isContainer) { openMiniListView(args.node); @@ -111,14 +111,11 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController", }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); - + $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; @@ -133,4 +130,4 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.MoveController", $scope.miniListView = node; } - }); \ No newline at end of file + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/content/copy.html b/src/Umbraco.Web.UI.Client/src/views/content/copy.html index ca7714c284..ee39f98234 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/copy.html @@ -51,7 +51,8 @@ hideheader="{{treeModel.hideHeader}}" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewexpand="true" enablecheckboxes="true"> @@ -90,4 +91,4 @@ Copy - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/content/move.html b/src/Umbraco.Web.UI.Client/src/views/content/move.html index f7978e01a5..39d287dd35 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/content/move.html @@ -52,7 +52,8 @@ hideheader="{{treeModel.hideHeader}}" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewexpand="true" enablecheckboxes="true"> @@ -80,4 +81,4 @@ Move - \ No newline at end of file + diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.controller.js index 15c173fe13..66863e6e87 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.controller.js @@ -2,9 +2,9 @@ angular.module("umbraco") .controller("Umbraco.Editors.DataType.MoveController", function ($scope, dataTypeResource, treeService, navigationService, notificationsService, appState, eventsService) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -60,9 +60,8 @@ angular.module("umbraco") }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html index 09390cdb81..4452f78234 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/datatypes/move.html @@ -30,7 +30,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.controller.js index c666a2159c..11af7448d1 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.controller.js @@ -2,9 +2,9 @@ angular.module("umbraco") .controller("Umbraco.Editors.DocumentTypes.CopyController", function ($scope, contentTypeResource, treeService, navigationService, notificationsService, appState, eventsService) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -55,9 +55,9 @@ angular.module("umbraco") }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html index db1a0db640..64b523ba70 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/copy.html @@ -31,7 +31,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.controller.js b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.controller.js index e82385477a..1ae38920d8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.controller.js @@ -2,9 +2,9 @@ angular.module("umbraco") .controller("Umbraco.Editors.DocumentTypes.MoveController", function ($scope, contentTypeResource, treeService, navigationService, notificationsService, appState, eventsService) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -60,9 +60,9 @@ angular.module("umbraco") }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html index c982abc0c0..e67288ad86 100644 --- a/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/documenttypes/move.html @@ -31,7 +31,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js index fe6e65918a..fd0267859f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.move.controller.js @@ -3,7 +3,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", function ($scope, userService, eventsService, mediaResource, appState, treeService, navigationService) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; var node = dialogOptions.currentNode; $scope.treeModel = { @@ -13,7 +13,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.treeModel.hideHeader = userData.startMediaIds.length > 0 && userData.startMediaIds.indexOf(-1) == -1; }); - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { if(args && args.event) { args.event.preventDefault(); @@ -31,15 +31,17 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.target.selected = true; } - function nodeExpandedHandler(ev, args) { + function nodeExpandedHandler(args) { // open mini list view for list views if (args.node.metaData.isContainer) { openMiniListView(args.node); } } - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.bind("treeNodeExpanded", nodeExpandedHandler); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + $scope.dialogTreeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + } $scope.move = function () { mediaResource.move({ parentId: $scope.target.id, id: node.id }) @@ -69,12 +71,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.error = err; }); }; - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - $scope.dialogTreeEventHandler.unbind("treeNodeExpanded", nodeExpandedHandler); - }); - + // Mini list view $scope.selectListViewNode = function (node) { node.selected = node.selected === true ? false : true; @@ -89,4 +86,4 @@ angular.module("umbraco").controller("Umbraco.Editors.Media.MoveController", $scope.miniListView = node; } - }); \ No newline at end of file + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/media/move.html b/src/Umbraco.Web.UI.Client/src/views/media/move.html index d04d66f706..0d36b67575 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/media/move.html @@ -30,7 +30,8 @@ hideheader="{{treeModel.hideHeader}}" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablelistviewexpand="true" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.controller.js index 2a1b2463f8..62d7a6be35 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.controller.js @@ -2,9 +2,9 @@ angular.module("umbraco") .controller("Umbraco.Editors.MediaTypes.CopyController", function ($scope, mediaTypeResource, treeService, navigationService, notificationsService, appState, eventsService) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -55,9 +55,8 @@ angular.module("umbraco") }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html index 319e59c4cc..62e5a4a749 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/copy.html @@ -31,7 +31,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.controller.js b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.controller.js index f9bb584de7..d2990c0c9d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.controller.js @@ -3,9 +3,9 @@ angular.module("umbraco") function ($scope, mediaTypeResource, treeService, navigationService, notificationsService, appState, eventsService) { var dialogOptions = $scope.dialogOptions; - $scope.dialogTreeEventHandler = $({}); + $scope.dialogTreeApi = {}; - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -61,9 +61,9 @@ angular.module("umbraco") }); }; - $scope.dialogTreeEventHandler.bind("treeNodeSelect", nodeSelectHandler); - - $scope.$on('$destroy', function () { - $scope.dialogTreeEventHandler.unbind("treeNodeSelect", nodeSelectHandler); - }); + $scope.onTreeInit = function () { + $scope.dialogTreeApi.callbacks.treeNodeSelect(nodeSelectHandler); + } + + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html index 59172eb547..96a72b0c32 100644 --- a/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html +++ b/src/Umbraco.Web.UI.Client/src/views/mediatypes/move.html @@ -30,7 +30,8 @@ hideheader="false" hideoptions="true" isdialog="true" - eventhandler="dialogTreeEventHandler" + api="dialogTreeApi" + on-init="onTreeInit()" enablecheckboxes="true"> diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 18b3d392de..f9a9fd09ec 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -265,13 +265,6 @@ sort.aspx ASPXCodeBehind - - publish.aspx - ASPXCodeBehind - - - publish.aspx - default.Master ASPXCodeBehind @@ -455,17 +448,7 @@ - - - - - - - - - - @@ -503,10 +486,6 @@ - - - - @@ -539,7 +518,6 @@ - @@ -662,7 +640,6 @@ Form - @@ -751,11 +728,9 @@ $(NuGetPackageFolders.Split(';')[0]) - - diff --git a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml index 66fc2bd1ff..140b411e31 100644 --- a/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml +++ b/src/Umbraco.Web.UI/umbraco/Views/Default.cshtml @@ -64,7 +64,7 @@ -
+
diff --git a/src/Umbraco.Web.UI/umbraco/actions/delete.aspx b/src/Umbraco.Web.UI/umbraco/actions/delete.aspx deleted file mode 100644 index 285080f0ce..0000000000 --- a/src/Umbraco.Web.UI/umbraco/actions/delete.aspx +++ /dev/null @@ -1,30 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="../masterpages/umbracoPage.Master" CodeBehind="delete.aspx.cs" Inherits="umbraco.presentation.actions.delete" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %> - - - - - - - - - - - -

-
-

- -

-
- - - -

-
- - -
-
diff --git a/src/Umbraco.Web.UI/umbraco/actions/editContent.aspx b/src/Umbraco.Web.UI/umbraco/actions/editContent.aspx deleted file mode 100644 index 4c785a15dd..0000000000 --- a/src/Umbraco.Web.UI/umbraco/actions/editContent.aspx +++ /dev/null @@ -1,16 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="editContent.aspx.cs" Inherits="umbraco.presentation.actions.editContent" %> - - - - - - Untitled Page - - -
-
- -
-
- - diff --git a/src/Umbraco.Web.UI/umbraco/actions/preview.aspx b/src/Umbraco.Web.UI/umbraco/actions/preview.aspx deleted file mode 100644 index ee5ed17e72..0000000000 --- a/src/Umbraco.Web.UI/umbraco/actions/preview.aspx +++ /dev/null @@ -1,16 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="preview.aspx.cs" Inherits="umbraco.presentation.actions.preview" %> - - - - - - Preview page - - -
-
- -
-
- - diff --git a/src/Umbraco.Web.UI/umbraco/actions/publish.aspx b/src/Umbraco.Web.UI/umbraco/actions/publish.aspx deleted file mode 100644 index 4fd73a96b6..0000000000 --- a/src/Umbraco.Web.UI/umbraco/actions/publish.aspx +++ /dev/null @@ -1,30 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="../masterpages/umbracoPage.Master" CodeBehind="publish.aspx.cs" Inherits="umbraco.presentation.actions.publish" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %> - - - - - - - - - - -

- -

-
-
-

- -

-
- - -

-
-
- -
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs b/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs deleted file mode 100644 index 2a6e65fc84..0000000000 --- a/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using Umbraco.Web.UI.Pages; - -namespace Umbraco.Web.UI.Umbraco.Dialogs -{ - public partial class Publish : UmbracoEnsuredPage - { - - protected string PageName { get; private set; } - protected int DocumentId { get; private set; } - protected string DocumentPath { get; private set; } - - protected override void OnInit(EventArgs e) - { - base.OnInit(e); - - int id; - if (!int.TryParse(Request.GetItemAsString("id"), out id)) - { - throw new InvalidOperationException("The id value must be an integer"); - } - - var doc = Services.ContentService.GetById(id); - if (doc == null) - { - throw new InvalidOperationException("No document found with id " + id); - } - - DocumentId = doc.Id; - PageName = Server.HtmlEncode(doc.Name); - DocumentPath = doc.Path; - - } - } -} diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs deleted file mode 100644 index 8d393f6f1d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/dialogs/Publish.aspx.designer.cs +++ /dev/null @@ -1,51 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Web.UI.Umbraco.Dialogs { - - - public partial class Publish { - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// ProgBar1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.ProgressBar ProgBar1; - } -} diff --git a/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx b/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx deleted file mode 100644 index 1882570d00..0000000000 --- a/src/Umbraco.Web.UI/umbraco/dialogs/publish.aspx +++ /dev/null @@ -1,98 +0,0 @@ -<%@ Page Language="c#" MasterPageFile="../masterpages/umbracoDialog.Master" CodeBehind="Publish.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Dialogs.Publish" %> - -<%@ Import Namespace="Umbraco.Core" %> -<%@ Import Namespace="Umbraco.Web" %> -<%@ Import Namespace="Umbraco.Web.Mvc" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %> - - - - - - - - - - - - - - -
- -
-

- <%= Services.TextService.Localize("publish/publishHelp", new[] { PageName}) %> -

- -
- - -
- -
- - -
- - - -
- - - -
-
-

- <%=Services.TextService.Localize("publish/inProgress")%> -

- -
-
-
- - - - - -
- -
diff --git a/src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.cs b/src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.cs deleted file mode 100644 index 4c81917beb..0000000000 --- a/src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; - -namespace Umbraco.Web.UI.Umbraco.Settings -{ - public partial class EditTemplate : global::umbraco.cms.presentation.settings.editTemplate - { - } -} diff --git a/src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.designer.cs deleted file mode 100644 index 7345824a88..0000000000 --- a/src/Umbraco.Web.UI/umbraco/settings/EditTemplate.aspx.designer.cs +++ /dev/null @@ -1,24 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Web.UI.Umbraco.Settings { - - - public partial class EditTemplate { - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - } -} diff --git a/src/Umbraco.Web.UI/umbraco/settings/editLanguage.aspx b/src/Umbraco.Web.UI/umbraco/settings/editLanguage.aspx deleted file mode 100644 index 68088ae594..0000000000 --- a/src/Umbraco.Web.UI/umbraco/settings/editLanguage.aspx +++ /dev/null @@ -1,19 +0,0 @@ -<%@ Page Language="c#" CodeBehind="editLanguage.aspx.cs" AutoEventWireup="True" MasterPageFile="../masterpages/umbracoPage.Master" - Inherits="umbraco.settings.editLanguage" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" Assembly="Umbraco.Web" %> - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/umbraco/settings/editTemplate.aspx b/src/Umbraco.Web.UI/umbraco/settings/editTemplate.aspx deleted file mode 100644 index 86cbceaad6..0000000000 --- a/src/Umbraco.Web.UI/umbraco/settings/editTemplate.aspx +++ /dev/null @@ -1,167 +0,0 @@ -<%@ Page MasterPageFile="../masterpages/umbracoPage.Master" Language="c#" CodeBehind="EditTemplate.aspx.cs" - ValidateRequest="false" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.Settings.EditTemplate" %> - -<%@ OutputCache Location="None" %> - -<%@ Import Namespace="Umbraco.Core" %> -<%@ Import Namespace="Umbraco.Core.Configuration" %> -<%@ Import Namespace="Umbraco.Core.IO" %> -<%@ Import Namespace="Umbraco.Web.Mvc" %> -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - Insert Inline Razor Macro - -
-
- - -
"> - <%# DataBinder.Eval(Container, "DataItem.Value") %> -
-
-
-
-
- - Insert Macro - -
-
- - -
" - params="<%# DoesMacroHaveSettings(Eval("id").ToString()) %>"> - <%# Eval("macroName")%> -
-
-
-
- -
diff --git a/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css b/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css deleted file mode 100644 index e1ac53be9d..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.css +++ /dev/null @@ -1,27 +0,0 @@ -#includeUnpublished { - margin-left: 16px; - margin-bottom: 20px; - margin-top: 5px; -} - -#animDiv > div { - margin-left:auto; - margin-right:auto; -} - -#container label{ - display: inline; -} - -.disabled { - color: #999; -} - -#feedbackMsg > div { - padding: 5px; -} - -#feedbackMsg ul { - margin: 0; - padding-left: 15px; -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js b/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js deleted file mode 100644 index d034a07a4a..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Dialogs/PublishDialog.js +++ /dev/null @@ -1,98 +0,0 @@ -Umbraco.Sys.registerNamespace("Umbraco.Dialogs"); - -(function ($) { - - Umbraco.Dialogs.PublishDialog = base2.Base.extend({ - - //private methods/variables - _opts: null, - _koViewModel: null, - - // Constructor - constructor: function () { - }, - - //public methods - - init: function (opts) { - /// Initializes the class and any UI bindings - - // Merge options with default - this._opts = $.extend({ - - }, opts); - - var self = this; - - //The knockout js view model for the selected item - self._koViewModel = { - publishAll: ko.observable(false), - includeUnpublished: ko.observable(false), - processStatus: ko.observable("init"), - isSuccessful: ko.observable(false), - resultMessages: ko.observableArray(), - resultMessage: ko.observable(""), //if there's only one result message - closeDialog: function () { - UmbClientMgr.closeModalWindow(); - }, - startPublish: function() { - this.processStatus("publishing"); - - $.post(self._opts.restServiceLocation + "PublishDocument", - JSON.stringify({ - documentId: self._opts.documentId, - publishDescendants: self._koViewModel.publishAll(), - includeUnpublished: self._koViewModel.includeUnpublished() - }), - function (e) { - self._koViewModel.processStatus("complete"); - self._koViewModel.isSuccessful(e.success); - var msgs = e.message.trim().split("\r\n"); - if (msgs.length > 1) { - for (var m in msgs) { - self._koViewModel.resultMessages.push({ message: msgs[m] }); - } - } - else { - self._koViewModel.resultMessage(msgs[0]); - } - - //sync the tree - UmbClientMgr.mainTree().setActiveTreeType('content'); - UmbClientMgr.mainTree().syncTree(self._opts.documentPath, true); - }); - } - }; - //ensure includeUnpublished is always false if publishAll is ever false - self._koViewModel.publishAll.subscribe(function (newValue) { - if (newValue === false) { - self._koViewModel.includeUnpublished(false); - } - }); - - ko.applyBindings(self._koViewModel); - } - - - }, { - //Static members - - //private methods/variables - _instance: null, - - // Singleton accessor - getInstance: function () { - if (this._instance == null) - this._instance = new Umbraco.Dialogs.PublishDialog(); - return this._instance; - } - }); - - //Set defaults for jQuery ajax calls. - $.ajaxSetup({ - dataType: 'json', - cache: false, - contentType: 'application/json; charset=utf-8' - }); - -})(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/DirectoryBrowser.css b/src/Umbraco.Web.UI/umbraco_client/Editors/DirectoryBrowser.css deleted file mode 100644 index e9e1a2b382..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/DirectoryBrowser.css +++ /dev/null @@ -1,28 +0,0 @@ -a -{ - color: #3C6B96; -} - -.tdDir a -{ - color: #3C6B96; - padding: 3px; - padding-left: 25px; - background: url(../../umbraco/images/foldericon.png) no-repeat 2px 2px; -} - -.tdFile a -{ - color: #3C6B96; - padding: 3px; - padding-left: 25px; - background: url(../../umbraco/images/file.png) no-repeat 2px 2px; -} - -small a -{ - color: #999; - padding-left: 3px !Important; - background-image: none !Important; - text-decoration: none; -} diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditMacro.css b/src/Umbraco.Web.UI/umbraco_client/Editors/EditMacro.css deleted file mode 100644 index f1a3e6e674..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditMacro.css +++ /dev/null @@ -1,36 +0,0 @@ -table.macro-props { - width: 98%; - border: 0; -} -table.macro-props td { - padding: 4px; -} -table.macro-props td.propertyHeader { - width: 200px; - vertical-align: middle; -} -table.macro-props td.propertyContent { - vertical-align: middle; -} -table.macro-props td.propertyContent .guiInputText { - width: 300px; -} -table.macro-props td.propertyContent .guiInputText.small -{ - width: 60px; - display: inline-block; -} - - -table.macro-props.params td.propertyHeader -{ - width: 25%; -} -table.macro-props.params td.propertyContent input, -table.macro-props.params td.propertyContent select -{ - width: 90%; -} -table.macro-props.params td.propertyContent input[type=submit] { - width: 100px; -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditStyleSheet.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditStyleSheet.js deleted file mode 100644 index 990ed3edee..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditStyleSheet.js +++ /dev/null @@ -1,109 +0,0 @@ -Umbraco.Sys.registerNamespace("Umbraco.Editors"); - -(function ($) { - - Umbraco.Editors.EditStyleSheet = base2.Base.extend({ - //private methods/variables - _opts: null, - - // Constructor - constructor: function(opts) { - // Merge options with default - this._opts = $.extend({ - - - // Default options go here - }, opts); - }, - - init: function() { - //setup UI elements - var self = this; - - //bind to the save event - this._opts.saveButton.click(function (event) { - event.preventDefault(); - self.doSubmit(); - }); - }, - - doSubmit: function() { - var self = this; - - var filename = this._opts.nameTxtBox.val(); - var codeval = this._opts.editorSourceElement.val(); - //if CodeMirror is not defined, then the code editor is disabled. - if (typeof(CodeMirror) != "undefined") { - codeval = UmbEditor.GetCode(); - } - - this.save( - filename, - self._opts.originalFileName, - codeval); - }, - - save: function (filename, oldName, contents) { - var self = this; - - $.post(self._opts.restServiceLocation + "SaveStylesheet", - JSON.stringify({ - filename: filename, - oldName: oldName, - contents: contents - }), - function (e) { - if (e.success) { - self.submitSuccess(e); - } else { - self.submitFailure(e.message, e.header); - } - }); - }, - - submitSuccess: function (args) { - var msg = args.message; - var header = args.header; - var path = this._opts.treeSyncPath; - var pathChanged = false; - if (args.path) { - if (path != args.path) { - pathChanged = true; - } - path = args.path; - } - if (args.contents) { - UmbEditor.SetCode(args.contents); - } - - UmbClientMgr.mainTree().setActiveTreeType("stylesheets"); - if (pathChanged) { - // file is used in url so we need to redirect - var qs = window.location.search; - if (qs.startsWith("?")) qs = qs.substring("?".length); - var qp1 = qs.split("&"); - var qp2 = []; - for (var i = 0; i < qp1.length; i++) - if (!qp1[i].startsWith("id=")) - qp2.push(qp1[i]); - - var location = window.location.pathname + "?" + qp2.join("&") + "&id=" + args.name; - UmbClientMgr.contentFrame(location); - - // need to do it after we navigate otherwise the navigation waits until the message timeout is done - top.UmbSpeechBubble.ShowMessage("save", header, msg); - } - else { - top.UmbSpeechBubble.ShowMessage("save", header, msg); - this._opts.lttPathElement.prop("href", args.url).html(args.url); - this._opts.originalFileName = args.name; - this._opts.treeSyncPath = args.path; - UmbClientMgr.mainTree().syncTree(path, true); - } - }, - - submitFailure: function(err, header) { - top.UmbSpeechBubble.ShowMessage('error', header, err); - } - }); -})(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js deleted file mode 100644 index e3a3ee4bf2..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditTemplate.js +++ /dev/null @@ -1,181 +0,0 @@ -Umbraco.Sys.registerNamespace("Umbraco.Editors"); - -(function ($) { - - Umbraco.Editors.EditTemplate = base2.Base.extend({ - //private methods/variables - _opts: null, - - _openMacroModal: function(alias) { - - var self = this; - - UmbClientMgr.openAngularModalWindow({ - template: "views/common/dialogs/insertmacro.html", - dialogData: { - renderingEngine: "WebForms", - macroData: { macroAlias: alias } - }, - callback: function(data) { - UmbEditor.Insert(data.syntax, '', self._opts.editorClientId); - } - }); - }, - - _insertMacro: function(alias) { - var macroElement = "umbraco:Macro"; - if (!this._opts.useMasterPages) { - macroElement = "?UMBRACO_MACRO"; - } - var cp = macroElement + ' Alias="' + alias + '" runat="server"'; - UmbEditor.Insert('<' + cp + ' />', '', this._opts.editorClientId); - }, - - _insertCodeBlockFromTemplate: function(templateId) { - var self = this; - $.ajax({ - type: "POST", - url: this._opts.umbracoPath + "/webservices/templates.asmx/GetCodeSnippet", - data: "{templateId: '" + templateId + "'}", - contentType: "application/json; charset=utf-8", - dataType: "json", - success: function(msg) { - - var cp = 'umbraco:Macro runat="server" language="cshtml"'; - UmbEditor.Insert('\n<' + cp + '>\n' + msg.d, '\n\n', self._opts.editorClientId); - - } - }); - }, - - _insertCodeBlock: function() { - var snip = this._umbracoInsertSnippet(); - UmbEditor.Insert(snip.BeginTag, snip.EndTag, this._opts.editorClientId); - }, - - _umbracoInsertSnippet: function() { - var snip = new UmbracoCodeSnippet(); - var cp = 'umbraco:Macro runat="server" language="cshtml"'; - snip.BeginTag = '\n<' + cp + '>\n'; - snip.EndTag = '\n<' + '/umbraco:Macro' + '>\n'; - snip.TargetId = this._opts.editorClientId; - return snip; - }, - - // Constructor - constructor: function(opts) { - // Merge options with default - this._opts = $.extend({ - - - // Default options go here - }, opts); - }, - - init: function() { - //Sets up the UI and binds events - - var self = this; - - //bind to the save event - this._opts.saveButton.click(function (event) { - event.preventDefault(); - self.doSubmit(); - }); - - $("#sb").click(function() { - self._insertCodeBlock(); - }); - $("#sbMacro").click(function() { - self._openMacroModal(); - }); - //macro split button - $('#sbMacro').splitbutton({ menu: '#macroMenu' }); - $("#splitButtonMacro").appendTo("#splitButtonMacroPlaceHolder"); - - ////razor macro split button - $('#sb').splitbutton({ menu: '#codeTemplateMenu' }); - $("#splitButton").appendTo("#splitButtonPlaceHolder"); - - $(".macro").click(function() { - var alias = $(this).attr("rel"); - if ($(this).attr("params") == "1") { - self._openMacroModal(alias); - } - else { - self._insertMacro(alias); - } - }); - - $(".codeTemplate").click(function() { - self._insertCodeBlockFromTemplate($(this).attr("rel")); - }); - }, - - doSubmit: function() { - this.save(jQuery('#' + this._opts.templateNameClientId).val(), jQuery('#' + this._opts.templateAliasClientId).val(), UmbEditor.GetCode()); - }, - - save: function(templateName, templateAlias, codeVal) { - var self = this; - - $.post(self._opts.restServiceLocation + "SaveTemplate", - JSON.stringify({ - templateName: templateName, - templateAlias: templateAlias, - templateContents: codeVal, - templateId: self._opts.templateId, - masterTemplateId: this._opts.masterPageDropDown.val() - }), - function (e) { - if (e.success) { - self.submitSuccess(e); - } else { - self.submitFailure(e.message, e.header); - } - }); - - }, - - submitSuccess: function (args) { - var msg = args.message; - var header = args.header; - var path = this._opts.treeSyncPath; - var pathChanged = false; - if (args.path) { - if (path != args.path) { - pathChanged = true; - } - path = args.path; - } - if (args.contents) { - UmbEditor.SetCode(args.contents); - } - - var alias = args.alias; - this._opts.aliasTxtBox.val(alias); - - top.UmbSpeechBubble.ShowMessage('save', header, msg); - UmbClientMgr.mainTree().setActiveTreeType('templates'); - if (pathChanged) { - UmbClientMgr.mainTree().moveNode(this._opts.templateId, path); - } - else { - UmbClientMgr.mainTree().syncTree(path, true); - } - - }, - - submitFailure: function (err, header) { - top.UmbSpeechBubble.ShowMessage('error', header, err); - } - }); - - //Set defaults for jQuery ajax calls. - $.ajaxSetup({ - dataType: 'json', - cache: false, - contentType: 'application/json; charset=utf-8' - }); - -})(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js deleted file mode 100644 index a93f4cf815..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditView.js +++ /dev/null @@ -1,288 +0,0 @@ -Umbraco.Sys.registerNamespace("Umbraco.Editors"); - -(function ($) { - - Umbraco.Editors.EditView = base2.Base.extend({ - /// Defines the EditView class to controll the persisting of the view file and UI interaction - - //private methods/variables - _opts: null, - - // Constructor - constructor: function (opts) { - // Merge options with default - this._opts = $.extend({ - // Default options go here - }, opts); - }, - - //public methods/variables - - init: function () { - var self = this; - //bind to the change of the master template drop down - this._opts.masterPageDropDown.change(function () { - self.changeMasterPageFile(); - }); - //bind to the save event - this._opts.saveButton.click(function (event) { - event.preventDefault(); - self.doSubmit(); - }); - }, - - insertMacroMarkup: function(alias) { - /// callback used to insert the markup for a macro with no parameters - - UmbEditor.Insert("@Umbraco.RenderMacro(\"" + alias + "\")", "", this._opts.codeEditorElementId); - }, - - insertRenderBody: function() { - UmbEditor.Insert("@RenderBody()", "", this._opts.codeEditorElementId); - }, - - openMacroModal: function (alias) { - /// callback used to display the modal dialog to insert a macro with parameters - - var self = this; - - UmbClientMgr.openAngularModalWindow({ - template: "views/common/dialogs/insertmacro.html", - dialogData: { - renderingEngine: "Mvc", - macroData: {macroAlias: alias} - }, - callback: function (data) { - UmbEditor.Insert(data.syntax, '', self._opts.codeEditorElementId); - } - }); - }, - - openSnippetModal: function (type) { - /// callback used to display the modal dialog to insert a macro with parameters - - var self = this; - - UmbClientMgr.openAngularModalWindow({ - template: "views/common/dialogs/template/snippet.html", - callback: function (data) { - - var code = ""; - - if (type === 'section') { - code = "\n@section " + data.name + "{\n"; - code += "\n" + - "}\n"; - } - - if (type === 'rendersection') { - if (data.required) { - code = "\n@RenderSection(\"" + data.name + "\", true)\n"; - } else { - code = "\n@RenderSection(\"" + data.name + "\", false)\n"; - } - } - - UmbEditor.Insert(code, '', self._opts.codeEditorElementId); - }, - type: type - }); - }, - - - openQueryModal: function () { - /// callback used to display the modal dialog to insert a macro with parameters - - var self = this; - - UmbClientMgr.openAngularModalWindow({ - template: "views/common/dialogs/template/queryBuilder.html", - callback: function (data) { - - //var dataFormatted = data.replace(new RegExp('[' + "." + ']', 'g'), "\n\t\t\t\t\t."); - - var code = "\n@{\n" + "\tvar selection = " + data + ";\n}\n"; - code += "
    \n" + - "\t@foreach(var item in selection){\n" + - "\t\t
  • \n" + - "\t\t\t@item.Name\n" + - "\t\t
  • \n" + - "\t}\n" + - "
\n\n"; - - UmbEditor.Insert(code, '', self._opts.codeEditorElementId); - } - }); - }, - - - doSubmit: function () { - /// Submits the data to the server for saving - var codeVal = UmbClientMgr.contentFrame().UmbEditor.GetCode(); - var self = this; - - if (this._opts.editorType == "Template") { - //saving a template view - - $.post(self._opts.restServiceLocation + "SaveTemplate", - JSON.stringify({ - templateName: this._opts.nameTxtBox.val(), - templateAlias: this._opts.aliasTxtBox.val(), - templateContents: codeVal, - templateId: this._opts.templateId, - masterTemplateId: this._opts.masterPageDropDown.val() - }), - function(e) { - if (e.success) { - self.submitSuccess(e); - } else { - self.submitFailure(e.message, e.header); - } - }); - } - else { - //saving a partial view - var actionName = this._opts.editorType === "PartialViewMacro" ? "SavePartialViewMacro" : "SavePartialView"; - - $.post(self._opts.restServiceLocation + actionName, - JSON.stringify({ - filename: this._opts.nameTxtBox.val(), - oldName: this._opts.originalFileName, - contents: codeVal - }), - function(e) { - if (e.success) { - self.submitSuccess(e); - } else { - self.submitFailure(e.message, e.header); - } - }); - } - }, - - submitSuccess: function (args) { - - var msg = args.message; - var header = args.header; - var path = this._opts.treeSyncPath; - var pathChanged = false; - if (args.path) { - if (path != args.path) { - pathChanged = true; - } - path = args.path; - } - if (args.contents) { - UmbEditor.SetCode(args.contents); - } else if (!this.IsSimpleEditor) { - // Restore focuse to text region. SetCode also does this. - UmbEditor._editor.focus(); - } - - UmbClientMgr.mainTree().setActiveTreeType(this._opts.currentTreeType); - - if (this._opts.editorType == "Template") { - - var alias = args.alias; - this._opts.aliasTxtBox.val(alias); - - top.UmbSpeechBubble.ShowMessage('save', header, msg); - - //templates are different because they are ID based, whereas view files are file based without a static id - - if (pathChanged) { - UmbClientMgr.mainTree().moveNode(this._opts.templateId, path); - this._opts.treeSyncPath = path; - } - else { - UmbClientMgr.mainTree().syncTree(path, true); - } - - } - else { - var newFilePath = this._opts.nameTxtBox.val(); - - - function trimStart(str, trim) { - if (str.startsWith(trim)) { - return str.substring(trim.length); - } - return str; - } - - //if the filename changes, we need to redirect since the file name is used in the url - if (this._opts.originalFileName != newFilePath) { - var queryParts = trimStart(window.location.search, "?").split('&'); - var notFileParts = []; - for (var i = 0; i < queryParts.length; i++) { - if (queryParts[i].substr(0, "file=".length) != "file=") { - notFileParts.push(queryParts[i]); - } - } - var newLocation = window.location.pathname + "?" + notFileParts.join("&") + "&file=" + newFilePath; - - UmbClientMgr.contentFrame(newLocation); - - //we need to do this after we navigate otherwise the navigation will wait unti lthe message timeout is done! - top.UmbSpeechBubble.ShowMessage('save', header, msg); - } - else { - - top.UmbSpeechBubble.ShowMessage('save', header, msg); - - if (args && args.name) { - this._opts.originalFileName = args.name; - } - if (args && args.path) { - this._opts.treeSyncPath = args.path; - } - - UmbClientMgr.mainTree().syncTree(path, true, null, newFilePath.split("/")[1]); - } - } - - }, - - submitFailure: function (err, header) { - top.UmbSpeechBubble.ShowMessage('error', header, err); - }, - - changeMasterPageFile: function ( ) { - //var editor = document.getElementById(this._opts.sourceEditorId); - var templateDropDown = this._opts.masterPageDropDown.get(0); - var templateCode = UmbClientMgr.contentFrame().UmbEditor.GetCode(); - var newValue = templateDropDown.options[templateDropDown.selectedIndex].id; - - var layoutDefRegex = new RegExp("(@{[\\s\\S]*?Layout\\s*?=\\s*?)(\"[^\"]*?\"|null)(;[\\s\\S]*?})", "gi"); - - if (newValue != undefined && newValue != "") { - if (layoutDefRegex.test(templateCode)) { - // Declaration exists, so just update it - templateCode = templateCode.replace(layoutDefRegex, "$1\"" + newValue + "\"$3"); - } else { - // Declaration doesn't exist, so prepend to start of doc - //TODO: Maybe insert at the cursor position, rather than just at the top of the doc? - templateCode = "@{\n\tLayout = \"" + newValue + "\";\n}\n" + templateCode; - } - } else { - if (layoutDefRegex.test(templateCode)) { - // Declaration exists, so just update it - templateCode = templateCode.replace(layoutDefRegex, "$1null$3"); - } - } - - UmbClientMgr.contentFrame().UmbEditor.SetCode(templateCode); - - return false; - } - }); - - - //Set defaults for jQuery ajax calls. - $.ajaxSetup({ - dataType: 'json', - cache: false, - contentType: 'application/json; charset=utf-8' - }); - -})(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.css b/src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.css deleted file mode 100644 index 975c68b0c2..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.css +++ /dev/null @@ -1,14 +0,0 @@ -#errorDiv -{ - margin-bottom: 10px; -} - - #errorDiv a - { - float: right; - } - -.propertyItemheader -{ - width: 200px !important; -} diff --git a/src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.js b/src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.js deleted file mode 100644 index 67f0259afb..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/Editors/EditXslt.js +++ /dev/null @@ -1,80 +0,0 @@ -Umbraco.Sys.registerNamespace("Umbraco.Editors"); - -(function ($) { - - Umbraco.Editors.EditXslt = base2.Base.extend({ - //private methods/variables - _opts: null, - - // Constructor - constructor: function(opts) { - // Merge options with default - this._opts = $.extend({ - - - // Default options go here - }, opts); - }, - - init: function () { - //setup UI elements - var self = this; - - //bind to the save event - this._opts.saveButton.click(function (event) { - event.preventDefault(); - self.doSubmit(); - }); - }, - - doSubmit: function () { - var self = this; - - var fileName = this._opts.nameTxtBox.val(); - var codeVal = this._opts.editorSourceElement.val(); - //if CodeMirror is not defined, then the code editor is disabled. - if (typeof (CodeMirror) != "undefined") { - codeVal = UmbEditor.GetCode(); - } - umbraco.presentation.webservices.codeEditorSave.SaveXslt( - fileName, self._opts.originalFileName, codeVal, true, - function (t) { self.submitSucces(t); }, - function (t) { self.submitFailure(t); }); - - }, - - submitSucces: function (t) { - if (t != 'true') { - top.UmbSpeechBubble.ShowMessage('error', 'Saving XSLT file failed',"
" + t + "
"); - } - - var newFilePath = this._opts.nameTxtBox.val(); - - //if the filename changes, we need to redirect since the file name is used in the url - if (this._opts.originalFileName != newFilePath) { - var newLocation = window.location.pathname + "?" + "&file=" + newFilePath; - - UmbClientMgr.contentFrame(newLocation); - - //we need to do this after we navigate otherwise the navigation will wait unti lthe message timeout is done! - top.UmbSpeechBubble.ShowMessage('save', 'XSLT file saved', ''); - } - else { - - top.UmbSpeechBubble.ShowMessage('save', 'XSLT file saved', ''); - UmbClientMgr.mainTree().setActiveTreeType('xslt'); - //we need to pass in the newId parameter so it knows which node to resync after retreival from the server - UmbClientMgr.mainTree().syncTree("-1,init," + this._opts.originalFileName, true, null, newFilePath); - //set the original file path to the new one - this._opts.originalFileName = newFilePath; - } - - - }, - - submitFailure: function (t) { - alert(t); - top.UmbSpeechBubble.ShowMessage('warning', 'XSLT file could not be saved', ''); - } - }); -})(jQuery); \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco_client/PunyCode/punycode.min.js b/src/Umbraco.Web.UI/umbraco_client/PunyCode/punycode.min.js deleted file mode 100644 index 5b5c120d4d..0000000000 --- a/src/Umbraco.Web.UI/umbraco_client/PunyCode/punycode.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! https://mths.be/punycode v1.3.2 by @mathias */ -!function (a) { function b(a) { throw RangeError(E[a]) } function c(a, b) { for (var c = a.length, d = []; c--;) d[c] = b(a[c]); return d } function d(a, b) { var d = a.split("@"), e = ""; d.length > 1 && (e = d[0] + "@", a = d[1]), a = a.replace(D, "."); var f = a.split("."), g = c(f, b).join("."); return e + g } function e(a) { for (var b, c, d = [], e = 0, f = a.length; f > e;) b = a.charCodeAt(e++), b >= 55296 && 56319 >= b && f > e ? (c = a.charCodeAt(e++), 56320 == (64512 & c) ? d.push(((1023 & b) << 10) + (1023 & c) + 65536) : (d.push(b), e--)) : d.push(b); return d } function f(a) { return c(a, function (a) { var b = ""; return a > 65535 && (a -= 65536, b += H(a >>> 10 & 1023 | 55296), a = 56320 | 1023 & a), b += H(a) }).join("") } function g(a) { return 10 > a - 48 ? a - 22 : 26 > a - 65 ? a - 65 : 26 > a - 97 ? a - 97 : t } function h(a, b) { return a + 22 + 75 * (26 > a) - ((0 != b) << 5) } function i(a, b, c) { var d = 0; for (a = c ? G(a / x) : a >> 1, a += G(a / b) ; a > F * v >> 1; d += t) a = G(a / F); return G(d + (F + 1) * a / (a + w)) } function j(a) { var c, d, e, h, j, k, l, m, n, o, p = [], q = a.length, r = 0, w = z, x = y; for (d = a.lastIndexOf(A), 0 > d && (d = 0), e = 0; d > e; ++e) a.charCodeAt(e) >= 128 && b("not-basic"), p.push(a.charCodeAt(e)); for (h = d > 0 ? d + 1 : 0; q > h;) { for (j = r, k = 1, l = t; h >= q && b("invalid-input"), m = g(a.charCodeAt(h++)), (m >= t || m > G((s - r) / k)) && b("overflow"), r += m * k, n = x >= l ? u : l >= x + v ? v : l - x, !(n > m) ; l += t) o = t - n, k > G(s / o) && b("overflow"), k *= o; c = p.length + 1, x = i(r - j, c, 0 == j), G(r / c) > s - w && b("overflow"), w += G(r / c), r %= c, p.splice(r++, 0, w) } return f(p) } function k(a) { var c, d, f, g, j, k, l, m, n, o, p, q, r, w, x, B = []; for (a = e(a), q = a.length, c = z, d = 0, j = y, k = 0; q > k; ++k) p = a[k], 128 > p && B.push(H(p)); for (f = g = B.length, g && B.push(A) ; q > f;) { for (l = s, k = 0; q > k; ++k) p = a[k], p >= c && l > p && (l = p); for (r = f + 1, l - c > G((s - d) / r) && b("overflow"), d += (l - c) * r, c = l, k = 0; q > k; ++k) if (p = a[k], c > p && ++d > s && b("overflow"), p == c) { for (m = d, n = t; o = j >= n ? u : n >= j + v ? v : n - j, !(o > m) ; n += t) x = m - o, w = t - o, B.push(H(h(o + x % w, 0))), m = G(x / w); B.push(H(h(m, 0))), j = i(d, r, f == g), d = 0, ++f } ++d, ++c } return B.join("") } function l(a) { return d(a, function (a) { return B.test(a) ? j(a.slice(4).toLowerCase()) : a }) } function m(a) { return d(a, function (a) { return C.test(a) ? "xn--" + k(a) : a }) } var n = "object" == typeof exports && exports && !exports.nodeType && exports, o = "object" == typeof module && module && !module.nodeType && module, p = "object" == typeof global && global; (p.global === p || p.window === p || p.self === p) && (a = p); var q, r, s = 2147483647, t = 36, u = 1, v = 26, w = 38, x = 700, y = 72, z = 128, A = "-", B = /^xn--/, C = /[^\x20-\x7E]/, D = /[\x2E\u3002\uFF0E\uFF61]/g, E = { overflow: "Overflow: input needs wider integers to process", "not-basic": "Illegal input >= 0x80 (not a basic code point)", "invalid-input": "Invalid input" }, F = t - u, G = Math.floor, H = String.fromCharCode; if (q = { version: "1.3.2", ucs2: { decode: e, encode: f }, decode: j, encode: k, toASCII: m, toUnicode: l }, "function" == typeof define && "object" == typeof define.amd && define.amd) define("punycode", function () { return q }); else if (n && o) if (module.exports == n) o.exports = q; else for (r in q) q.hasOwnProperty(r) && (n[r] = q[r]); else a.punycode = q }(this); \ No newline at end of file diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 60ef3cf529..f723ae17ae 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -211,7 +211,6 @@ namespace Umbraco.Web.Trees AddActionNode(item, menu, convert: true); AddActionNode(item, menu, convert: true); - AddActionNode(item, menu, true, true); AddActionNode(item, menu, convert: true); AddActionNode(item, menu, convert: true); AddActionNode(item, menu, convert: true); diff --git a/src/Umbraco.Web/UI/Pages/ClientTools.cs b/src/Umbraco.Web/UI/Pages/ClientTools.cs index 7b59725101..e997f64153 100644 --- a/src/Umbraco.Web/UI/Pages/ClientTools.cs +++ b/src/Umbraco.Web/UI/Pages/ClientTools.cs @@ -54,7 +54,6 @@ namespace Umbraco.Web.UI.Pages public static string CopyNode { get { return GetMainTree + ".copyNode('{0}', '{1}');"; } } public static string MoveNode { get { return GetMainTree + ".moveNode('{0}', '{1}');"; } } public static string ReloadActionNode { get { return GetMainTree + ".reloadActionNode({0}, {1}, null);"; } } - public static string SetActiveTreeType { get { return GetMainTree + ".setActiveTreeType('{0}');"; } } public static string RefreshTree { get { return GetMainTree + ".refreshTree();"; } } public static string RefreshTreeType { get { return GetMainTree + ".refreshTree('{0}');"; } } public static string CloseModalWindow() @@ -283,25 +282,6 @@ namespace Umbraco.Web.UI.Pages return this; } - /// - /// When the application searches for a node, it searches for nodes in specific tree types. - /// If SyncTree is used, it will sync the tree nodes with the active tree type, therefore if - /// a developer wants to sync a specific tree, they can call this method to set the type to sync. - /// - /// - /// Each branch of a particular tree should theoretically be the same type, however, developers can - /// override the type of each branch in their BaseTree's but this is not standard practice. If there - /// are multiple types of branches in one tree, then only those branches that have the Active tree type - /// will be searched for syncing. - /// - /// - /// - public ClientTools SetActiveTreeType(string treeType) - { - RegisterClientScript(string.Format(Scripts.SetActiveTreeType, treeType)); - return this; - } - /// /// Closes the Umbraco dialog window if it is open /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index eb057193e4..0869104282 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1265,33 +1265,6 @@ Code - - delete.aspx - ASPXCodeBehind - - - delete.aspx - - - editContent.aspx - ASPXCodeBehind - - - editContent.aspx - - - preview.aspx - ASPXCodeBehind - - - preview.aspx - - - publish.aspx - - - publish.aspx - @@ -1483,13 +1456,6 @@ EditDictionaryItem.aspx - - editLanguage.aspx - ASPXCodeBehind - - - editLanguage.aspx - Code @@ -1636,7 +1602,6 @@ ASPXCodeBehind - Form @@ -1661,12 +1626,6 @@ ASPXCodeBehind - - - - - ASPXCodeBehind - diff --git a/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs b/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs index d48e91a504..6d87239fb3 100644 --- a/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs +++ b/src/Umbraco.Web/_Legacy/Actions/ActionPublish.cs @@ -43,7 +43,7 @@ namespace Umbraco.Web._Legacy.Actions { get { - return string.Format("{0}.actionPublish()", ClientTools.Scripts.GetAppActions); + return string.Empty; } } @@ -67,7 +67,7 @@ namespace Umbraco.Web._Legacy.Actions { get { - return "globe"; + return string.Empty; } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx deleted file mode 100644 index 4ea4a2f81b..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx +++ /dev/null @@ -1,30 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="../masterpages/umbracoPage.Master" CodeBehind="delete.aspx.cs" Inherits="umbraco.presentation.actions.delete" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" %> - - - - - - - - - - - -

-
-

- -

-
- - - -

-
- - -
-
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.cs deleted file mode 100644 index f7bee05d28..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web; -using Umbraco.Web.Composing; -using Umbraco.Web.UI.Pages; - -namespace umbraco.presentation.actions -{ - public partial class delete : UmbracoEnsuredPage - { - private IContent c; - - protected void Page_Load(object sender, EventArgs e) - { - c = Current.Services.ContentService.GetById(int.Parse(Request.GetItemAsString("id"))); - - if (Security.ValidateUserApp(Constants.Applications.Content) == false) - throw new ArgumentException("The current user doesn't have access to this application. Please contact the system administrator."); - CheckPathAndPermissions(c.Id, UmbracoObjectTypes.Document, Umbraco.Web._Legacy.Actions.ActionDelete.Instance); - - pane_delete.Text = Services.TextService.Localize("delete") + " '" + c.Name + "'"; - Panel2.Text = Services.TextService.Localize("delete"); - warning.Text = Services.TextService.Localize("confirmdelete") + " '" + c.Name + "'"; - deleteButton.Text = Services.TextService.Localize("delete"); - } - - protected void deleteButton_Click(object sender, EventArgs e) - { - deleteMessage.Text = Services.TextService.Localize("deleted"); - deleted.Text = "'" + c.Name + "' " + Services.TextService.Localize("deleted"); - deleteMessage.Visible = true; - confirm.Visible = false; - - Current.Services.ContentService.Delete(c); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.designer.cs deleted file mode 100644 index dc80441bb7..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/delete.aspx.designer.cs +++ /dev/null @@ -1,78 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.presentation.actions { - - - public partial class delete { - - /// - /// Panel2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.UmbracoPanel Panel2; - - /// - /// confirm control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel confirm; - - /// - /// pane_delete control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Pane pane_delete; - - /// - /// warning control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal warning; - - /// - /// deleteButton control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button deleteButton; - - /// - /// deleteMessage control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Pane deleteMessage; - - /// - /// deleted control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal deleted; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx deleted file mode 100644 index 4c785a15dd..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx +++ /dev/null @@ -1,16 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="editContent.aspx.cs" Inherits="umbraco.presentation.actions.editContent" %> - - - - - - Untitled Page - - -
-
- -
-
- - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.cs deleted file mode 100644 index 46674c95ba..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Data; -using System.Configuration; -using System.Collections; -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 Umbraco.Web; -using Umbraco.Web.UI.Pages; - -namespace umbraco.presentation.actions -{ - - /// - /// This page is used only to deeplink to the edit content page with the tree - /// - public partial class editContent : UmbracoEnsuredPage - { - protected void Page_Load(object sender, EventArgs e) - { - Response.Redirect("../umbraco.aspx?app=content&rightAction=editContent&id=" + Request.GetItemAsString("id") + "#content", true); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.designer.cs deleted file mode 100644 index ae6deb3ac0..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/editContent.aspx.designer.cs +++ /dev/null @@ -1,31 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.312 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.presentation.actions { - - - /// - /// editContent class. - /// - /// - /// Auto-generated class. - /// - public partial class editContent { - - /// - /// form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm form1; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx deleted file mode 100644 index ee5ed17e72..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx +++ /dev/null @@ -1,16 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="preview.aspx.cs" Inherits="umbraco.presentation.actions.preview" %> - - - - - - Preview page - - -
-
- -
-
- - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.cs deleted file mode 100644 index 1baebd3478..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Umbraco.Core; -using Umbraco.Core.IO; -using Umbraco.Web; -using Umbraco.Web.UI.Pages; - -namespace umbraco.presentation.actions -{ - public partial class preview : UmbracoEnsuredPage - { - - public preview() - { - CurrentApp = Constants.Applications.Content; - - } - /// - /// Handles the Load event of the Page control. - /// - /// The source of the event. - /// The instance containing the event data. - protected void Page_Load(object sender, EventArgs e) - { - Response.Redirect(IOHelper.ResolveUrl(string.Format("{0}/dialogs/preview.aspx?id= {1}", SystemDirectories.Umbraco, int.Parse(Request.GetItemAsString("id"))))); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.designer.cs deleted file mode 100644 index b9e434581a..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/preview.aspx.designer.cs +++ /dev/null @@ -1,31 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:2.0.50727.832 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.presentation.actions { - - - /// - /// preview class. - /// - /// - /// Auto-generated class. - /// - public partial class preview { - - /// - /// form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm form1; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx deleted file mode 100644 index b4d8a81c32..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx +++ /dev/null @@ -1,30 +0,0 @@ -<%@ Page Language="C#" AutoEventWireup="true" MasterPageFile="../masterpages/umbracoPage.Master" CodeBehind="publish.aspx.cs" Inherits="umbraco.presentation.actions.publish" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" %> - - - - - - - - - - -

- -

-
-
-

- -

-
- - -

-
-
- -
\ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs deleted file mode 100644 index 41c5a54cb5..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs +++ /dev/null @@ -1,88 +0,0 @@ -//TODO: REbuild this in angular and new apis then remove this - -//using System; -//using System.Data; -//using System.Configuration; -//using System.Collections; -//using System.Linq; -//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 Umbraco.Core.Publishing; -//using umbraco.cms.businesslogic.web; -//using Umbraco.Core; - -//namespace umbraco.presentation.actions -//{ -// public partial class publish : Umbraco.Web.UI.Pages.UmbracoEnsuredPage -// { -// private Document d; - -// protected void Page_Load(object sender, EventArgs e) -// { -// d = new Document(int.Parse(helper.Request("id"))); - -// if (!base.ValidateUserApp(Constants.Applications.Content)) -// throw new ArgumentException("The current user doesn't have access to this application. Please contact the system administrator."); - -// if (!base.ValidateUserNodeTreePermissions(d.Path, "U")) -// throw new ArgumentException("The current user doesn't have permissions to publish this document. Please contact the system administrator."); - -// pane_publish.Text = Services.TextService.Localize("publish") + " '" + d.Text + "'"; -// Panel2.Text = Services.TextService.Localize("publish"); -// warning.Text = Services.TextService.Localize("publish") + " '" + d.Text + "'. " + Services.TextService.Localize("areyousure"); -// deleteButton.Text = Services.TextService.Localize("publish"); -// } - -// protected void deleteButton_Click(object sender, EventArgs e) -// { -// deleteMessage.Visible = true; -// deleteMessage.Text = Services.TextService.Localize("editContentPublishedHeader"); - -// confirm.Visible = false; - -// var result = d.SaveAndPublishWithResult(UmbracoUser); -// if (result.Success) -// { -// deleted.Text = Services.TextService.Localize("editContentPublishedHeader") + " ('" + d.Text + "') " + Services.TextService.Localize("editContentPublishedText") + "

" + Services.TextService.Localize("view") + " " + d.Text + ""; -// } -// else -// { -// deleted.Text = "

" + GetMessageForStatus(result.Result) + "
"; -// } - -// } - -// private string GetMessageForStatus(PublishStatus status) -// { -// switch (status.StatusType) -// { -// case PublishStatusType.Success: -// case PublishStatusType.SuccessAlreadyPublished: -// return Services.TextService.Localize("speechBubbles/editContentPublishedText"); -// case PublishStatusType.FailedPathNotPublished: -// return ui.Text("publish", "contentPublishedFailedByParent", -// string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), -// UmbracoUser).Trim(); -// case PublishStatusType.FailedCancelledByEvent: -// return Services.TextService.Localize("speechBubbles/contentPublishedFailedByEvent"); -// case PublishStatusType.FailedHasExpired: -// case PublishStatusType.FailedAwaitingRelease: -// case PublishStatusType.FailedIsTrashed: -// return "Cannot publish document with a status of " + status.StatusType; -// case PublishStatusType.FailedContentInvalid: -// return ui.Text("publish", "contentPublishedFailedInvalid", -// new[] -// { -// string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), -// string.Join(",", status.InvalidProperties.Select(x => x.Alias)) -// }, UmbracoUser); -// default: -// throw new IndexOutOfRangeException(); -// } -// } -// } -//} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.designer.cs deleted file mode 100644 index d8b50f4c96..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.designer.cs +++ /dev/null @@ -1,78 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.presentation.actions { - - - public partial class publish { - - /// - /// Panel2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.UmbracoPanel Panel2; - - /// - /// confirm control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel confirm; - - /// - /// pane_publish control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Pane pane_publish; - - /// - /// warning control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal warning; - - /// - /// deleteButton control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button deleteButton; - - /// - /// deleteMessage control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Pane deleteMessage; - - /// - /// deleted control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal deleted; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs index 420002f9b3..163e1da2b8 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs @@ -45,7 +45,6 @@ namespace umbraco.cms.presentation.developer if (IsPostBack == false) { ClientTools - .SetActiveTreeType(Constants.Trees.Macros) .SyncTree("-1," + _macro.Id, false); string tempMacroAssembly = _macro.ControlAssembly ?? ""; @@ -290,7 +289,6 @@ namespace umbraco.cms.presentation.developer Page.Validate(); ClientTools - .SetActiveTreeType(Constants.Trees.Macros) .SyncTree("-1," + _macro.Id.ToInvariantString(), true); //true forces the reload var tempMacroAssembly = macroAssembly.Text; diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs index e33c113135..15d71625c3 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Packages/editPackage.aspx.cs @@ -58,7 +58,6 @@ namespace umbraco.presentation.developer.packages if (Page.IsPostBack == false) { ClientTools - .SetActiveTreeType(Constants.Trees.Packages) .SyncTree("-1,created," + createdPackage.Data.Id, false); packageAuthorName.Text = pack.Author; @@ -194,7 +193,6 @@ namespace umbraco.presentation.developer.packages else { ClientTools - .SetActiveTreeType(Constants.Trees.Packages) .SyncTree("-1,created," + createdPackage.Data.Id, true); } } 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 c32f086373..82bc42a2e6 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,6 @@ namespace umbraco.cms.presentation.developer string file = Request.QueryString["file"]; string path = BaseTree.GetTreePathFromFilePath(file, false, true); ClientTools - .SetActiveTreeType(Constants.Trees.Xslt) .SyncTree(path, false); } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/EditDictionaryItem.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/EditDictionaryItem.aspx.cs index 5676a98a3a..42217d1fa2 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/EditDictionaryItem.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/EditDictionaryItem.aspx.cs @@ -92,7 +92,6 @@ namespace umbraco.settings { var path = BuildPath(currentItem); ClientTools - .SetActiveTreeType(Constants.Trees.Dictionary) .SyncTree(path, false); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx deleted file mode 100644 index a985543c6d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx +++ /dev/null @@ -1,19 +0,0 @@ -<%@ Page Language="c#" CodeBehind="editLanguage.aspx.cs" AutoEventWireup="True" MasterPageFile="../masterpages/umbracoPage.Master" - Inherits="umbraco.settings.editLanguage" %> -<%@ Register TagPrefix="cc1" Namespace="Umbraco.Web._Legacy.Controls" %> - - - - - - - - - - - - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.cs deleted file mode 100644 index 4b4bf36740..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections; -using System.Globalization; -using System.Web.UI.WebControls; -using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Services; -using Umbraco.Web; -using Umbraco.Web.Composing; -using Umbraco.Web.UI; - -namespace umbraco.settings -{ - /// - /// Summary description for editLanguage. - /// - [WebformsPageTreeAuthorize(Constants.Trees.Languages)] - public partial class editLanguage : Umbraco.Web.UI.Pages.UmbracoEnsuredPage - { - public editLanguage() - { - CurrentApp = Constants.Applications.Settings.ToString(); - - } - protected System.Web.UI.WebControls.TextBox NameTxt; - protected System.Web.UI.WebControls.Literal DisplayName; - //cms.businesslogic.language.Language currentLanguage; - private ILanguage lang; - - protected void Page_Load(object sender, System.EventArgs e) - { - //currentLanguage = new cms.businesslogic.language.Language(int.Parse(Request.GetItemAsString("id"))); - lang = Current.Services.LocalizationService.GetLanguageById(int.Parse(Request.GetItemAsString("id"))); - - - // Put user code to initialize the page here - Panel1.Text = Services.TextService.Localize("editlanguage"); - pp_language.Text = Services.TextService.Localize("language/displayName"); - if (!IsPostBack) - { - updateCultureList(); - - ClientTools - .SetActiveTreeType(Constants.Trees.Languages) - .SyncTree(Request.GetItemAsString("id"), false); - } - - } - - private void updateCultureList() - { - SortedList sortedCultures = new SortedList(); - Cultures.Items.Clear(); - Cultures.Items.Add(new ListItem(Services.TextService.Localize("choose") + "...", "")); - foreach (CultureInfo ci in CultureInfo.GetCultures(CultureTypes.AllCultures)) - sortedCultures.Add(ci.DisplayName + "|||" + Guid.NewGuid().ToString(), ci.Name); - - IDictionaryEnumerator ide = sortedCultures.GetEnumerator(); - while (ide.MoveNext()) - { - ListItem li = new ListItem(ide.Key.ToString().Substring(0, ide.Key.ToString().IndexOf("|||")), ide.Value.ToString()); - if (ide.Value.ToString() == lang.IsoCode) - li.Selected = true; - - Cultures.Items.Add(li); - } - } - - private void save_click(object sender, EventArgs e) - { - //currentLanguage.CultureAlias = Cultures.SelectedValue; - //currentLanguage.Save(); - lang.IsoCode = Cultures.SelectedValue; - Current.Services.LocalizationService.Save(lang); - updateCultureList(); - - ClientTools.ShowSpeechBubble(SpeechBubbleIcon.Save, Services.TextService.Localize("speechBubbles/languageSaved"), ""); - } - - #region Web Form Designer generated code - override protected void OnInit(EventArgs e) - { - Panel1.hasMenu = true; - var save = Panel1.Menu.NewButton(); - save.Click += save_click; - save.ToolTip = Services.TextService.Localize("save"); - save.Text = Services.TextService.Localize("save"); - save.ID = "save"; - save.ButtonType = Umbraco.Web._Legacy.Controls.MenuButtonType.Primary; - - Panel1.Text = Services.TextService.Localize("language/editLanguage"); - - InitializeComponent(); - base.OnInit(e); - } - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - - } - #endregion - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.designer.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.designer.cs deleted file mode 100644 index 1fdc6da7f5..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/settings/editLanguage.aspx.designer.cs +++ /dev/null @@ -1,51 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace umbraco.settings { - - - public partial class editLanguage { - - /// - /// Panel1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.UmbracoPanel Panel1; - - /// - /// Pane7 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.Pane Pane7; - - /// - /// pp_language control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web._Legacy.Controls.PropertyPanel pp_language; - - /// - /// Cultures control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.DropDownList Cultures; - } -} 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 e831bd4757..5551228665 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 @@ -63,7 +63,6 @@ namespace umbraco.cms.presentation.settings.stylesheet if (IsPostBack == false) { ClientTools - .SetActiveTreeType(Constants.Trees.Stylesheets) .SyncTree(TreeSyncPath, false); } } 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 7c90a9a16b..f87889147d 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 @@ -64,9 +64,7 @@ namespace umbraco.cms.presentation.settings.stylesheet var nodePath = string.Format(BaseTree.GetTreePathFromFilePath(path) + ",{0}_{1}", path, HttpUtility.UrlEncode(_stylesheetproperty.Name)); - ClientTools - .SetActiveTreeType(Constants.Trees.Stylesheets) - .SyncTree(nodePath, IsPostBack); + ClientTools.SyncTree(nodePath, IsPostBack); prStyles.Attributes["style"] = _stylesheetproperty.Value; From b5b643e04c0a4793644bbb9558d485cb9e0698c4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 17 Apr 2018 00:09:53 +1000 Subject: [PATCH 03/10] fixes up the activeTree issue --- .../components/tree/umbtree.directive.js | 132 +++++++++--------- 1 file changed, 67 insertions(+), 65 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js index c1a8b4b8a0..e8c3f9cea9 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js @@ -160,95 +160,94 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat } if (!args.path) { throw "args.path cannot be null"; - } - if (!args.tree) { - throw "args.tree cannot be null"; + } + + var treeNode = loadActiveTree(args.tree); + + if (angular.isString(args.path)) { + args.path = args.path.replace('"', '').split(','); } - //this should normally be set unless it is being called from legacy - // code, so set the active tree type before proceeding. - if (args.tree) { - var treeNode = getTreeRootNode(args.tree); - - if (angular.isString(args.path)) { - args.path = args.path.replace('"', '').split(','); + //Filter the path for root node ids (we don't want to pass in -1 or 'init') + + args.path = _.filter(args.path, function (item) { return (item !== "init" && item !== "-1"); }); + + //Once those are filtered we need to check if the current user has a special start node id, + // if they do, then we're going to trim the start of the array for anything found from that start node + // and previous so that the tree syncs properly. The tree syncs from the top down and if there are parts + // of the tree's path in there that don't actually exist in the dom/model then syncing will not work. + + return userService.getCurrentUser().then(function (userData) { + + var startNodes = []; + for (var i = 0; i < userData.startContentIds; i++) { + startNodes.push(userData.startContentIds[i]); + } + for (var j = 0; j < userData.startMediaIds; j++) { + startNodes.push(userData.startMediaIds[j]); } - //Filter the path for root node ids (we don't want to pass in -1 or 'init') - - args.path = _.filter(args.path, function (item) { return (item !== "init" && item !== "-1"); }); - - //Once those are filtered we need to check if the current user has a special start node id, - // if they do, then we're going to trim the start of the array for anything found from that start node - // and previous so that the tree syncs properly. The tree syncs from the top down and if there are parts - // of the tree's path in there that don't actually exist in the dom/model then syncing will not work. - - return userService.getCurrentUser().then(function (userData) { - - var startNodes = []; - for (var i = 0; i < userData.startContentIds; i++) { - startNodes.push(userData.startContentIds[i]); - } - for (var j = 0; j < userData.startMediaIds; j++) { - startNodes.push(userData.startMediaIds[j]); - } - - _.each(startNodes, function (i) { - var found = _.find(args.path, function (p) { - return String(p) === String(i); - }); - if (found) { - args.path = args.path.splice(_.indexOf(args.path, found)); - } - }); - - deleteAnimations = false; - - return treeService.syncTree({ - node: treeNode, - path: args.path, - forceReload: args.forceReload - }).then(function (data) { - - if (args.activate === undefined || args.activate === true) { - $scope.currentNode = data; - } - - emitEvent("treeSynced", { node: data, activate: args.activate }); - - enableDeleteAnimations(); - - return $q.when({ node: data, activate: args.activate }); + _.each(startNodes, function (i) { + var found = _.find(args.path, function (p) { + return String(p) === String(i); }); + if (found) { + args.path = args.path.splice(_.indexOf(args.path, found)); + } }); - } + + deleteAnimations = false; + + return treeService.syncTree({ + node: treeNode, + path: args.path, + forceReload: args.forceReload + }).then(function (data) { + + if (args.activate === undefined || args.activate === true) { + $scope.currentNode = data; + } + + emitEvent("treeSynced", { node: data, activate: args.activate }); + + enableDeleteAnimations(); + + return $q.when({ node: data, activate: args.activate }); + }); + }); } - //given a tree alias, this will search the current section tree for the specified tree alias return it's root node - function getTreeRootNode(treeAlias) { - if (!treeAlias) { - throw "Err in umbtree.directive.loadActiveTree, treeAlias is null"; - } + //given a tree alias, this will search the current section tree for the specified tree alias and set the current active tree to it's root node + function loadActiveTree(treeAlias) { + if (!$scope.tree) { throw "Err in umbtree.directive.loadActiveTree, $scope.tree is null"; } + + //if its not specified, it should have been specified before + if (!treeAlias) { + if (!$scope.activeTree) { + throw "Err in umbtree.directive.loadActiveTree, $scope.activeTree is null"; + } + return $scope.activeTree; + } var childrenAndSelf = [$scope.tree.root].concat($scope.tree.root.children); - var found = _.find(childrenAndSelf, function (node) { + $scope.activeTree = _.find(childrenAndSelf, function (node) { if (node && node.metaData && node.metaData.treeAlias) { return node.metaData.treeAlias.toUpperCase() === treeAlias.toUpperCase(); } return false; }); - if (!found) { + if (!$scope.activeTree) { throw "Could not find the tree " + treeAlias; } - emitEvent("activeTreeLoaded", { tree: found }); + emitEvent("activeTreeLoaded", { tree: $scope.activeTree }); - return found; + return $scope.activeTree; } /** Method to load in the tree data */ @@ -276,6 +275,9 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat enableDeleteAnimations(); $scope.loading = false; + + //set the root as the current active tree + $scope.activeTree = $scope.tree.root; emitEvent("treeLoaded", { tree: $scope.tree }); emitEvent("treeNodeExpanded", { tree: $scope.tree, node: $scope.tree.root, children: $scope.tree.root.children }); From f7719773f2497d2acbf4009cf9d1f829100289e8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 17 Apr 2018 00:38:32 +1000 Subject: [PATCH 04/10] fixes passing in the element and clicking on a root node --- .../directives/components/tree/umbtree.directive.js | 8 ++++---- .../src/controllers/navigation.controller.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js index e8c3f9cea9..064a34e14b 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/tree/umbtree.directive.js @@ -51,7 +51,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat }; }, - controller: function ($scope) { + controller: function ($scope, $element) { var vm = this; @@ -372,7 +372,7 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat about it. */ $scope.options = function (n, ev) { - emitEvent("treeOptionsClick", { element: elem, node: n, event: ev }); + emitEvent("treeOptionsClick", { element: $element, node: n, event: ev }); }; /** @@ -393,11 +393,11 @@ function umbTreeDirective($compile, $log, $q, $rootScope, treeService, notificat //reset current node selection $scope.currentNode = null; - emitEvent("treeNodeSelect", { element: elem, node: n, event: ev }); + emitEvent("treeNodeSelect", { element: $element, node: n, event: ev }); }; $scope.altSelect = function (n, ev) { - emitEvent("treeNodeAltSelect", { element: elem, tree: $scope.tree, node: n, event: ev }); + emitEvent("treeNodeAltSelect", { element: $element, tree: $scope.tree, node: n, event: ev }); }; //watch for section changes diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index 1cb2760ec2..f0b3ddb915 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -95,8 +95,8 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, //not legacy, lets just set the route value and clear the query string if there is one. $location.path(n.routePath).search(""); } - else if (args.element.section) { - $location.path(args.element.section).search(""); + else if (n.section) { + $location.path(n.section).search(""); } navigationService.hideNavigation(); From d45112f2aba7abe2dfa08b0791894190e1c07955 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 17 Apr 2018 01:37:35 +1000 Subject: [PATCH 05/10] Gets the content tree controller to return the names for items per language (with mock data), wires up the navigation.controller to re-build the tree for the new language --- .../src/common/services/tree.service.js | 37 +++++++- .../src/controllers/navigation.controller.js | 82 ++++++++++++++++- .../treepicker/treepicker.controller.js | 88 ++++++------------- .../application/umb-navigation.html | 5 +- .../Trees/ContentTreeController.cs | 5 +- .../Trees/ContentTreeControllerBase.cs | 51 ++++++++--- 6 files changed, 186 insertions(+), 82 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js index 859ffba037..2d1beeae1a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js @@ -35,7 +35,42 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS _getTreeCache: function() { return treeCache; }, - + + /** Internal method to track expanded paths on a tree */ + _trackExpandedPaths: function (node, expandedPaths) { + if (!node.children || !angular.isArray(node.children) || node.children.length == 0) { + return; + } + + //take the last child + var childPath = this.getPath(node.children[node.children.length - 1]).join(","); + //check if this already exists, if so exit + if (expandedPaths.indexOf(childPath) !== -1) { + return; + } + + if (expandedPaths.length === 0) { + expandedPaths.push(childPath); //track it + return; + } + + var clonedPaths = expandedPaths.slice(0); //make a copy to iterate over so we can modify the original in the iteration + + _.each(clonedPaths, function (p) { + if (childPath.startsWith(p + ",")) { + //this means that the node's path supercedes this path stored so we can remove the current 'p' and replace it with node.path + expandedPaths.splice(expandedPaths.indexOf(p), 1); //remove it + expandedPaths.push(childPath); //replace it + } + else if (p.startsWith(childPath + ",")) { + //this means we've already tracked a deeper node so we shouldn't track this one + } + else { + expandedPaths.push(childPath); //track it + } + }); + }, + /** Internal method that ensures there's a routePath, parent and level property on each tree node and adds some icon specific properties so that the nodes display properly */ _formatNodeDataForUseInUI: function (parentNode, treeNodes, section, level) { //if no level is set, then we make it 1 diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index f0b3ddb915..a8d6eccf7b 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -9,12 +9,15 @@ * * @param {navigationService} navigationService A reference to the navigationService */ -function NavigationController($scope, $rootScope, $location, $log, $routeParams, $timeout, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper, languageResource) { +function NavigationController($scope, $rootScope, $location, $log, $q, $routeParams, $timeout, treeService, appState, navigationService, keyboardService, dialogService, historyService, eventsService, sectionResource, angularHelper, languageResource) { $scope.treeApi = {}; //Bind to the main tree events $scope.onTreeInit = function () { + + $scope.treeApi.callbacks.treeNodeExpanded(nodeExpandedHandler); + //when a tree is loaded into a section, we need to put it into appState $scope.treeApi.callbacks.treeLoaded(function (args) { appState.setTreeState("currentRootNode", args.tree); @@ -106,11 +109,13 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, eventsService.emit("app.navigationReady", { treeApi: $scope.treeApi}); } - //Put the navigation service on this scope so we can use it's methods/properties in the view. + //TODO: Remove this, this is not healthy + // Put the navigation service on this scope so we can use it's methods/properties in the view. // IMPORTANT: all properties assigned to this scope are generally available on the scope object on dialogs since // when we create a dialog we pass in this scope to be used for the dialog's scope instead of creating a new one. $scope.nav = navigationService; - // TODO: Lets fix this, it is less than ideal to be passing in the navigationController scope to something else to be used as it's scope, + // TODO: Remove this, this is not healthy + // it is less than ideal to be passing in the navigationController scope to something else to be used as it's scope, // this is going to lead to problems/confusion. I really don't think passing scope's around is very good practice. $rootScope.nav = navigationService; @@ -127,7 +132,11 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, $scope.page.languageSelectorIsOpen = false; $scope.currentSection = appState.getSectionState("currentSection"); + $scope.customTreeParams = null; + $scope.treeCacheKey = "_"; $scope.showNavigation = appState.getGlobalState("showNavigation"); + // tracks all expanded paths so when the language is switched we can resync it with the already loaded paths + var expandedPaths = []; //trigger search with a hotkey: keyboardService.bind("ctrl+shift+s", function () { @@ -238,10 +247,77 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, })); + /** + * Updates the tree's query parameters + */ + function initTree() { + //create the custom query string param for this tree + var queryParams = {}; + if ($scope.selectedLanguage && $scope.selectedLanguage.id) { + queryParams["languageId"] = $scope.selectedLanguage.id; + } + var queryString = $.param(queryParams); //create the query string from the params object + + if (queryString) { + $scope.customTreeParams = queryString; + $scope.treeCacheKey = queryString; // this tree uses caching but we need to change it's cache key per lang + } + else { + $scope.treeCacheKey = "_"; // this tree uses caching, there's no lang selected so use the default + } + } + + function nodeExpandedHandler(args) { + //store the reference to the expanded node path + if (args.node) { + treeService._trackExpandedPaths(args.node, expandedPaths); + } + } + $scope.selectLanguage = function(language, languages) { $scope.selectedLanguage = language; // close the language selector $scope.page.languageSelectorIsOpen = false; + + initTree(); //this will reset the tree params and the tree directive will pick up the changes in a $watch + + //reload the tree with it's updated querystring args + $scope.treeApi.load($scope.currentSection).then(function () { + + //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in + //sequence but that's what we need to do here + + + //re-sync to currently edited node + var currNode = appState.getTreeState("selectedNode"); + //create the list of promises + var promises = []; + //starting with syncing to the currently selected node if there is one + if (currNode) { + var path = treeService.getPath(currNode); + promises.push($scope.treeApi.syncTree({ path: path, activate: true })); + } + for (var i = 0; i < expandedPaths.length; i++) { + promises.push($scope.treeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + } + + //now execute them in sequence... sorry there's no other good way to do it with angular promises + var j = 0; + function pExec(promise) { + j++; + promise.then(function (data) { + if (j === promises.length) { + return $q.when(data); //exit + } + else { + return pExec(promises[j]); //recurse + } + }); + } + if (promises.length > 0) { + pExec(promises[0]); //start the promise chain + } + }); }; //this reacts to the options item in the tree diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index 29b4710eea..028e27305b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -194,82 +194,46 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", initTree(); //this will reset the tree params and the tree directive will pick up the changes in a $watch - $timeout(function () { //execute in the next digest since the $watch needs to update first + //reload the tree with it's updated querystring args + vm.dialogTreeApi.load(vm.section).then(function () { - //reload the tree with it's updated querystring args - vm.dialogTreeApi.load(vm.section).then(function () { + //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in + //sequence but that's what we need to do here - //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in - //sequence but that's what we need to do here + //create the list of promises + var promises = []; + for (var i = 0; i < expandedPaths.length; i++) { + promises.push(vm.dialogTreeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + } - //create the list of promises - var promises = []; - for (var i = 0; i < expandedPaths.length; i++) { - promises.push(vm.dialogTreeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); - } - - //now execute them in sequence... sorry there's no other good way to do it with angular promises - var j = 0; - function pExec(promise) { - j++; - promise.then(function (data) { - if (j === promises.length) { - return $q.when(data); //exit - } - else { - return pExec(promises[j]); //recurse - } - }); - } + //now execute them in sequence... sorry there's no other good way to do it with angular promises + var j = 0; + function pExec(promise) { + j++; + promise.then(function (data) { + if (j === promises.length) { + return $q.when(data); //exit + } + else { + return pExec(promises[j]); //recurse + } + }); + } + if (promises.length > 0) { pExec(promises[0]); //start the promise chain - }); + } }); }; function toggleLanguageSelector() { vm.languageSelectorIsOpen = !vm.languageSelectorIsOpen; }; - - function trackExpandedPaths(node) { - - if (!node.children || !angular.isArray(node.children) || node.children.length == 0) { - return; - } - - //take the last child - var childPath = treeService.getPath(node.children[node.children.length - 1]).join(","); - //check if this already exists, if so exit - if (expandedPaths.indexOf(childPath) !== -1) { - return; - } - - if (expandedPaths.length === 0) { - expandedPaths.push(childPath); //track it - return; - } - - var clonedPaths = expandedPaths.slice(0); //make a copy to iterate over so we can modify the original in the iteration - - _.each(clonedPaths, function (p) { - if (childPath.startsWith(p + ",")) { - //this means that the node's path supercedes this path stored so we can remove the current 'p' and replace it with node.path - expandedPaths.splice(expandedPaths.indexOf(p), 1); //remove it - expandedPaths.push(childPath); //replace it - } - else if (p.startsWith(childPath + ",")) { - //this means we've already tracked a deeper node so we shouldn't track this one - } - else { - expandedPaths.push(childPath); //track it - } - }); - } - + function nodeExpandedHandler(args) { //store the reference to the expanded node path if (args.node) { - trackExpandedPaths(args.node); + treeService._trackExpandedPaths(args.node, expandedPaths); } // open mini list view for list views diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html index 91f1231ae7..0dd3851c6d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html @@ -18,10 +18,11 @@
+ section="{{currentSection}}" + customtreeparams="{{customTreeParams}}">
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index f723ae17ae..53528484d1 100644 --- a/src/Umbraco.Web/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web/Trees/ContentTreeController.cs @@ -47,10 +47,11 @@ namespace Umbraco.Web.Trees /// protected override TreeNode GetSingleTreeNode(IEntitySlim entity, string parentId, FormDataCollection queryStrings) { + var langId = queryStrings["languageId"].TryConvertTo(); + var allowedUserOptions = GetAllowedUserMenuItemsForNode(entity); - if (CanUserAccessNode(entity, allowedUserOptions)) + if (CanUserAccessNode(entity, allowedUserOptions, langId.Success ? langId.Result : null)) { - //Special check to see if it ia a container, if so then we'll hide children. var isContainer = entity.IsContainer; // && (queryStrings.Get("isDialog") != "true"); diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs index dd27c80382..ceb62aedfe 100644 --- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs +++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs @@ -14,7 +14,7 @@ using Umbraco.Web.Models.Trees; using Umbraco.Web.WebApi.Filters; using System.Globalization; using Umbraco.Core.Models.Entities; -using Umbraco.Web._Legacy.Actions; +using Umbraco.Web._Legacy.Actions; namespace Umbraco.Web.Trees { @@ -148,8 +148,9 @@ namespace Umbraco.Web.Trees } // get child entities - if id is root, but user's start nodes do not contain the - // root node, this returns the start nodes instead of root's children - var entities = GetChildEntities(id).ToList(); + // root node, this returns the start nodes instead of root's children + var langId = queryStrings["languageId"].TryConvertTo(); + var entities = GetChildEntities(id, langId.Success ? langId.Result : null).ToList(); nodes.AddRange(entities.Select(x => GetSingleTreeNodeWithAccessCheck(x, id, queryStrings)).Where(x => x != null)); // if the user does not have access to the root node, what we have is the start nodes, @@ -181,7 +182,7 @@ namespace Umbraco.Web.Trees protected abstract UmbracoObjectTypes UmbracoObjectType { get; } - protected IEnumerable GetChildEntities(string id) + protected IEnumerable GetChildEntities(string id, int? langId) { // try to parse id as an integer else use GetEntityFromId // which will grok Guids, Udis, etc and let use obtain the id @@ -193,17 +194,42 @@ namespace Umbraco.Web.Trees entityId = entity.Id; } + + IEntitySlim[] result; // if a request is made for the root node but user has no access to // root node, return start nodes instead if (entityId == Constants.System.Root && UserStartNodes.Contains(Constants.System.Root) == false) { - return UserStartNodes.Length > 0 - ? Services.EntityService.GetAll(UmbracoObjectType, UserStartNodes) - : Enumerable.Empty(); - } - - return Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToArray(); + result = UserStartNodes.Length > 0 + ? Services.EntityService.GetAll(UmbracoObjectType, UserStartNodes).ToArray() + : Array.Empty(); + } + else + { + result = Services.EntityService.GetChildren(entityId, UmbracoObjectType).ToArray(); + } + + if (langId.HasValue) + { + //need to update all node names + //TODO: This is not currently stored, we need to wait until U4-11128 is complete for this to work, in the meantime + // we'll mock using this and it will just be some mock data + foreach(var e in result) + { + if (e.AdditionalData.TryGetValue("VariantNames", out var variantNames)) + { + var casted = (IDictionary)variantNames; + e.Name = casted[langId.Value]; + } + else + { + e.Name = e.Name + " (lang: " + langId.Value + ")"; + } + } + } + + return result; } /// @@ -362,8 +388,9 @@ namespace Umbraco.Web.Trees /// A list of MenuItems that the user has permissions to execute on the current document /// By default the user must have Browse permissions to see the node in the Content tree /// - internal bool CanUserAccessNode(IUmbracoEntity doc, IEnumerable allowedUserOptions) - { + internal bool CanUserAccessNode(IUmbracoEntity doc, IEnumerable allowedUserOptions, int? langId) + { + //TODO: At some stage when we implement permissions on languages we'll need to take care of langId return allowedUserOptions.Select(x => x.Action).OfType().Any(); } From e234eb22f64133ab919a3cc9c464430fa073edba Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 17 Apr 2018 01:41:06 +1000 Subject: [PATCH 06/10] ensure the language tree changing is done after the digest --- .../src/controllers/navigation.controller.js | 70 ++++++++++--------- .../treepicker/treepicker.controller.js | 53 +++++++------- 2 files changed, 65 insertions(+), 58 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index a8d6eccf7b..d82c6d4307 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -281,43 +281,47 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar initTree(); //this will reset the tree params and the tree directive will pick up the changes in a $watch - //reload the tree with it's updated querystring args - $scope.treeApi.load($scope.currentSection).then(function () { + //execute after next digest because the internal watch on the customtreeparams needs to be bound now that we've changed it + $timeout(function () { + //reload the tree with it's updated querystring args + $scope.treeApi.load($scope.currentSection).then(function () { - //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in - //sequence but that's what we need to do here + //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in + //sequence but that's what we need to do here - - //re-sync to currently edited node - var currNode = appState.getTreeState("selectedNode"); - //create the list of promises - var promises = []; - //starting with syncing to the currently selected node if there is one - if (currNode) { - var path = treeService.getPath(currNode); - promises.push($scope.treeApi.syncTree({ path: path, activate: true })); - } - for (var i = 0; i < expandedPaths.length; i++) { - promises.push($scope.treeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); - } - //now execute them in sequence... sorry there's no other good way to do it with angular promises - var j = 0; - function pExec(promise) { - j++; - promise.then(function (data) { - if (j === promises.length) { - return $q.when(data); //exit - } - else { - return pExec(promises[j]); //recurse - } - }); - } - if (promises.length > 0) { - pExec(promises[0]); //start the promise chain - } + //re-sync to currently edited node + var currNode = appState.getTreeState("selectedNode"); + //create the list of promises + var promises = []; + //starting with syncing to the currently selected node if there is one + if (currNode) { + var path = treeService.getPath(currNode); + promises.push($scope.treeApi.syncTree({ path: path, activate: true })); + } + for (var i = 0; i < expandedPaths.length; i++) { + promises.push($scope.treeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + } + + //now execute them in sequence... sorry there's no other good way to do it with angular promises + var j = 0; + function pExec(promise) { + j++; + promise.then(function (data) { + if (j === promises.length) { + return $q.when(data); //exit + } + else { + return pExec(promises[j]); //recurse + } + }); + } + if (promises.length > 0) { + pExec(promises[0]); //start the promise chain + } + }); }); + }; //this reacts to the options item in the tree diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index 028e27305b..2180db1c64 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -194,34 +194,37 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", initTree(); //this will reset the tree params and the tree directive will pick up the changes in a $watch - //reload the tree with it's updated querystring args - vm.dialogTreeApi.load(vm.section).then(function () { + //execute after next digest because the internal watch on the customtreeparams needs to be bound now that we've changed it + $timeout(function () { + //reload the tree with it's updated querystring args + vm.dialogTreeApi.load(vm.section).then(function () { - //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in - //sequence but that's what we need to do here + //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in + //sequence but that's what we need to do here - //create the list of promises - var promises = []; - for (var i = 0; i < expandedPaths.length; i++) { - promises.push(vm.dialogTreeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); - } + //create the list of promises + var promises = []; + for (var i = 0; i < expandedPaths.length; i++) { + promises.push(vm.dialogTreeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + } - //now execute them in sequence... sorry there's no other good way to do it with angular promises - var j = 0; - function pExec(promise) { - j++; - promise.then(function (data) { - if (j === promises.length) { - return $q.when(data); //exit - } - else { - return pExec(promises[j]); //recurse - } - }); - } - if (promises.length > 0) { - pExec(promises[0]); //start the promise chain - } + //now execute them in sequence... sorry there's no other good way to do it with angular promises + var j = 0; + function pExec(promise) { + j++; + promise.then(function (data) { + if (j === promises.length) { + return $q.when(data); //exit + } + else { + return pExec(promises[j]); //recurse + } + }); + } + if (promises.length > 0) { + pExec(promises[0]); //start the promise chain + } + }); }); }; From 2872d0b0a2ec82bc0237450686ea2769a7fea610 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 17 Apr 2018 14:43:17 +1000 Subject: [PATCH 07/10] Fixes tree init logic when user isn't logged in, moves sequential promise chaining to a helper funciton, updates the route promise chaining to actual chain. --- .../common/services/angularhelper.service.js | 37 ++++++++++++- .../src/controllers/navigation.controller.js | 29 ++-------- src/Umbraco.Web.UI.Client/src/init.js | 39 +++++++------- src/Umbraco.Web.UI.Client/src/routes.js | 54 +++++++++---------- .../treepicker/treepicker.controller.js | 24 ++------- .../application/umb-navigation.html | 2 +- .../Umbraco/Views/AuthorizeUpgrade.cshtml | 5 +- .../umbraco/Views/Default.cshtml | 2 +- .../Editors/BackOfficeController.cs | 17 ++---- src/Umbraco.Web/Editors/BackOfficeModel.cs | 17 ++++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + 11 files changed, 117 insertions(+), 110 deletions(-) create mode 100644 src/Umbraco.Web/Editors/BackOfficeModel.cs diff --git a/src/Umbraco.Web.UI.Client/src/common/services/angularhelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/angularhelper.service.js index fb4d8216e3..24db2e5989 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/angularhelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/angularhelper.service.js @@ -8,7 +8,42 @@ */ function angularHelper($log, $q) { return { - + + /** + * Execute a list of promises sequentially. Unlike $q.all which executes all promises at once, this will execute them in sequence. + * @param {} promises + * @returns {} + */ + executeSequentialPromises: function (promises) { + + //this is sequential promise chaining, it's not pretty but we need to do it this way. + //$q.all doesn't execute promises in sequence but that's what we want to do here. + + if (!angular.isArray(promises)) { + throw "promises must be an array"; + } + + //now execute them in sequence... sorry there's no other good way to do it with angular promises + var j = 0; + function pExec(promise) { + j++; + return promise.then(function (data) { + if (j === promises.length) { + return $q.when(data); //exit + } + else { + return pExec(promises[j]); //recurse + } + }); + } + if (promises.length > 0) { + return pExec(promises[0]); //start the promise chain + } + else { + return $q.when(true); // just exit, no promises to execute + } + }, + /** * @ngdoc function * @name safeApply diff --git a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js index d82c6d4307..88896285e2 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -286,10 +286,6 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar //reload the tree with it's updated querystring args $scope.treeApi.load($scope.currentSection).then(function () { - //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in - //sequence but that's what we need to do here - - //re-sync to currently edited node var currNode = appState.getTreeState("selectedNode"); //create the list of promises @@ -299,26 +295,11 @@ function NavigationController($scope, $rootScope, $location, $log, $q, $routePar var path = treeService.getPath(currNode); promises.push($scope.treeApi.syncTree({ path: path, activate: true })); } - for (var i = 0; i < expandedPaths.length; i++) { - promises.push($scope.treeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); - } - - //now execute them in sequence... sorry there's no other good way to do it with angular promises - var j = 0; - function pExec(promise) { - j++; - promise.then(function (data) { - if (j === promises.length) { - return $q.when(data); //exit - } - else { - return pExec(promises[j]); //recurse - } - }); - } - if (promises.length > 0) { - pExec(promises[0]); //start the promise chain - } + //for (var i = 0; i < expandedPaths.length; i++) { + // promises.push($scope.treeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); + //} + //execute them sequentially + angularHelper.executeSequentialPromises(promises); }); }); diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index 666fcfdf5d..7fb35a4cd0 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -16,28 +16,29 @@ app.run(['userService', '$q', '$log', '$rootScope', '$location', 'queryStrings', /** Listens for authentication and checks if our required assets are loaded, if/once they are we'll broadcast a ready event */ eventsService.on("app.authenticated", function (evt, data) { - - $q.all([ - assetsService._loadInitAssets(), - userService.loadMomentLocaleForCurrentUser(), - tourService.registerAllTours() - ]).then(function () { - //Register all of the tours on the server - tourService.registerAllTours().then(function () { - appReady(data); + assetsService._loadInitAssets().then(function() { + $q.all([ + userService.loadMomentLocaleForCurrentUser(), + tourService.registerAllTours() + ]).then(function () { - // Auto start intro tour - tourService.getTourByAlias("umbIntroIntroduction").then(function (introTour) { - // start intro tour if it hasn't been completed or disabled - if (introTour && introTour.disabled !== true && introTour.completed !== true) { - tourService.startTour(introTour); - } + //Register all of the tours on the server + tourService.registerAllTours().then(function () { + appReady(data); + + // Auto start intro tour + tourService.getTourByAlias("umbIntroIntroduction").then(function (introTour) { + // start intro tour if it hasn't been completed or disabled + if (introTour && introTour.disabled !== true && introTour.completed !== true) { + tourService.startTour(introTour); + } + }); + + }, function () { + appAuthenticated = true; + appReady(data); }); - - }, function () { - appAuthenticated = true; - appReady(data); }); }); diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index 3fc4d3f78e..5f660cf212 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -1,54 +1,56 @@ app.config(function ($routeProvider) { - - /** This checks if the user is authenticated for a route and what the isRequired is set to. - Depending on whether isRequired = true, it first check if the user is authenticated and will resolve successfully + + /** + * This determines if the route can continue depending on authentication and initialization requirements + * @param {boolean} authRequired If true, it first checks if the user is authenticated and will resolve successfully otherwise the route will fail and the $routeChangeError event will execute, in that handler we will redirect to the rejected - path that is resolved from this method and prevent default (prevent the route from executing) */ - var canRoute = function(isRequired) { + path that is resolved from this method and prevent default (prevent the route from executing) + * @param {boolean} navRequired if true, the route can only continue once the main navigation is ready + * @returns {promise} + */ + var canRoute = function(authRequired) { return { /** Checks that the user is authenticated, then ensures that are requires assets are loaded */ isAuthenticatedAndReady: function ($q, userService, $route, assetsService, appState) { - var deferred = $q.defer(); - + //don't need to check if we've redirected to login and we've already checked auth if (!$route.current.params.section && ($route.current.params.check === false || $route.current.params.check === "false")) { - deferred.resolve(true); - return deferred.promise; + return $q.when(true); } - userService.isAuthenticated() + return userService.isAuthenticated() .then(function () { - assetsService._loadInitAssets().then(function() { + return assetsService._loadInitAssets().then(function () { //This could be the first time has loaded after the user has logged in, in this case // we need to broadcast the authenticated event - this will be handled by the startup (init) // handler to set/broadcast the ready state var broadcast = appState.getGlobalState("isReady") !== true; - userService.getCurrentUser({ broadcastEvent: broadcast }).then(function (user) { + return userService.getCurrentUser({ broadcastEvent: broadcast }).then(function (user) { //is auth, check if we allow or reject - if (isRequired) { - + if (authRequired) { + //This checks the current section and will force a redirect to 'content' as the default if ($route.current.params.section.toLowerCase() === "default" || $route.current.params.section.toLowerCase() === "umbraco" || $route.current.params.section === "") { $route.current.params.section = "content"; - } + } // U4-5430, Benjamin Howarth // We need to change the current route params if the user only has access to a single section // To do this we need to grab the current user's allowed sections, then reject the promise with the correct path. if (user.allowedSections.indexOf($route.current.params.section) > -1) { //this will resolve successfully so the route will continue - deferred.resolve(true); + return $q.when(true); } else { - deferred.reject({ path: "/" + user.allowedSections[0] }); + return $q.reject({ path: "/" + user.allowedSections[0] }); } } else { - deferred.reject({ path: "/" }); + return $q.reject({ path: "/" }); } }); @@ -56,17 +58,17 @@ app.config(function ($routeProvider) { }, function () { //not auth, check if we allow or reject - if (isRequired) { + if (authRequired) { //the check=false is checked above so that we don't have to make another http call to check //if they are logged in since we already know they are not. - deferred.reject({ path: "/login/false" }); + return $q.reject({ path: "/login/false" }); } else { //this will resolve successfully so the route will continue - deferred.resolve(true); + return $q.when(true); } }); - return deferred.promise; + } }; }; @@ -75,15 +77,13 @@ app.config(function ($routeProvider) { var doLogout = function() { return { isLoggedOut: function ($q, userService) { - var deferred = $q.defer(); - userService.logout().then(function () { + return userService.logout().then(function () { //success so continue - deferred.resolve(true); + return $q.when(true); }, function() { //logout failed somehow ? we'll reject with the login page i suppose - deferred.reject({ path: "/login/false" }); + return $q.reject({ path: "/login/false" }); }); - return deferred.promise; } } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js index 2180db1c64..c5ad32e0dc 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/overlays/treepicker/treepicker.controller.js @@ -198,32 +198,14 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", $timeout(function () { //reload the tree with it's updated querystring args vm.dialogTreeApi.load(vm.section).then(function () { - - //this is sequential promise chaining, it's not pretty but we need to do it this way. $q.all doesn't execute promises in - //sequence but that's what we need to do here - + //create the list of promises var promises = []; for (var i = 0; i < expandedPaths.length; i++) { promises.push(vm.dialogTreeApi.syncTree({ path: expandedPaths[i], activate: false, forceReload: true })); - } - - //now execute them in sequence... sorry there's no other good way to do it with angular promises - var j = 0; - function pExec(promise) { - j++; - promise.then(function (data) { - if (j === promises.length) { - return $q.when(data); //exit - } - else { - return pExec(promises[j]); //recurse - } - }); - } - if (promises.length > 0) { - pExec(promises[0]); //start the promise chain } + //execute them sequentially + angularHelper.executeSequentialPromises(promises); }); }); }; diff --git a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html index 0dd3851c6d..a470bfe307 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/application/umb-navigation.html @@ -16,7 +16,7 @@ -
+
@{ Layout = null; @@ -25,7 +26,7 @@ - + @@ -59,7 +60,7 @@ redirectUrl = Url.Action("AuthorizeUpgrade", "BackOffice") }); } - @Html.BareMinimumServerVariablesScript(Url, externalLoginUrl, Model.Features) + @Html.BareMinimumServerVariablesScript(Url, externalLoginUrl, Model.Features, Model.GlobalSettings)