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 335d27d5c4..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 @@ -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,405 +48,384 @@ 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 = ""; + }; + }, + + controller: function ($scope, $element) { + + 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; - //setup a default internal handler - if (!scope.eventhandler) { - scope.eventhandler = $({}); + /** 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 + }); + } + } + + /** 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) { + + if (!node) { + node = $scope.currentNode; } - //flag to enable/disable delete animations - var deleteAnimations = false; + 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"; + } + + var treeNode = loadActiveTree(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') - /** Helper function to emit tree events */ - function emitEvent(eventName, args) { - if (scope.eventhandler) { - $(scope.eventhandler).trigger(eventName, args); + 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]); } - } - - /** 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; - loadTree(); - }; - - scope.eventhandler.reloadNode = function (node) { - - if (!node) { - node = scope.currentNode; - } - - if (node) { - scope.loadChildren(node, true); - } - }; - - /** - 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"; - } - - var deferred = $q.defer(); - - //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); - }; + for (var j = 0; j < userData.startMediaIds; j++) { + startNodes.push(userData.startMediaIds[j]); } - } - - //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); + _.each(startNodes, function (i) { + var found = _.find(args.path, function (p) { + return String(p) === String(i); }); - } - } - - - //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; - } - - scope.activeTree = undefined; - - 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; - }); - - if (!scope.activeTree) { - throw "Could not find the tree " + treeAlias + ", activeTree has not been set"; + if (found) { + args.path = args.path.splice(_.indexOf(args.path, found)); } - - //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 }); - }); - } - 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); - }); - } - } - - - /** 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 }; - - //add the extra query string params if specified - if (scope.customtreeparams) { - args["queryString"] = scope.customtreeparams; - } - - treeService.getTree(args) - .then(function (data) { - //set the data once we have it - scope.tree = data; - - 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 }); - - }, function (reason) { - scope.loading = false; - notificationsService.error("Tree Error", reason); - }); - } - } - - /** syncs the tree, the treeNode can be ANY tree node in the tree that requires syncing */ - function syncTree(treeNode, path, forceReload, activate) { - + }); + deleteAnimations = false; - treeService.syncTree({ + return treeService.syncTree({ node: treeNode, - path: path, - forceReload: forceReload + path: args.path, + forceReload: args.forceReload }).then(function (data) { - if (activate === undefined || activate === true) { - scope.currentNode = data; + if (args.activate === undefined || args.activate === true) { + $scope.currentNode = data; } - emitEvent("treeSynced", { node: data, activate: activate }); + emitEvent("treeSynced", { node: data, activate: args.activate }); - enableDeleteAnimations(); + 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 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); + $scope.activeTree = _.find(childrenAndSelf, function (node) { + if (node && node.metaData && node.metaData.treeAlias) { + return node.metaData.treeAlias.toUpperCase() === treeAlias.toUpperCase(); + } + return false; + }); + + if (!$scope.activeTree) { + throw "Could not find the tree " + treeAlias; } - /** Returns the css classses assigned to the node (div element) */ - scope.getNodeCssClass = function (node) { - if (!node) { - return ''; + emitEvent("activeTreeLoaded", { tree: $scope.activeTree }); + + return $scope.activeTree; + } + + /** 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 }; + + //add the extra query string params if specified + if ($scope.customtreeparams) { + args["queryString"] = $scope.customtreeparams; } - //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. + return treeService.getTree(args) + .then(function (data) { + //set the data once we have it + $scope.tree = data; - var css = []; - if (node.cssClasses) { - _.each(node.cssClasses, function (c) { - css.push(c); + 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 }); + return $q.when(data); + }, function (reason) { + $scope.loading = false; + notificationsService.error("Tree Error", reason); + return $q.reject(reason); }); - } - - return css.join(" "); - }; + } + else { + return $q.reject(); + } + } - scope.selectEnabledNodeClass = function (node) { - return node ? - node.selected ? - 'icon umb-tree-icon sprTree icon-check green temporary' : - '' : - ''; - }; + /** Returns the css classses assigned to the node (div element) */ + $scope.getNodeCssClass = function (node) { + if (!node) { + return ''; + } - /** 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 {}; - } - }; + //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. - /* helper to force reloading children of a tree node */ - scope.loadChildren = function (node, forceReload) { - var deferred = $q.defer(); + var css = []; + if (node.cssClasses) { + _.each(node.cssClasses, function (c) { + css.push(c); + }); + } - //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 and customtreeparams changes - scope.$watchCollection("[section, customtreeparams]", 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: $element, 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: $element, node: n, event: ev }); + }; + + $scope.altSelect = function (n, ev) { + emitEvent("treeNodeAltSelect", { element: $element, 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..edd6e9d608 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,7 +244,7 @@ angular.module("umbraco.directives") scope.loadChildren(scope.node); } - var template = ''; + var template = ''; var newElement = angular.element(template); $compile(newElement)(scope); element.append(newElement); 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/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/menuactions.service.js b/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js index 7200e1f6f8..d9e95ff309 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/menuactions.service.js @@ -8,7 +8,7 @@ * @description * Defines the methods that are called when menu items declare only an action to execute */ -function umbracoMenuActions($q, treeService, $location, navigationService, appState, localizationService, userResource, umbRequestHelper, notificationsService) { +function umbracoMenuActions(treeService, $location, navigationService, appState, localizationService, usersResource, umbRequestHelper, notificationsService) { return { @@ -34,7 +34,7 @@ function umbracoMenuActions($q, treeService, $location, navigationService, appSt localizationService.localize("defaultdialogs_confirmdisable").then(function (txtConfirmDisable) { var currentMenuNode = UmbClientMgr.mainTree().getActionNode(); if (confirm(txtConfirmDisable + ' "' + args.entity.name + '"?\n\n')) { - userResource.disableUser(args.entity.id).then(function () { + usersResource.disableUser(args.entity.id).then(function () { navigationService.syncTree({ tree: args.treeAlias, path: [args.entity.parentId, args.entity.id], forceReload: true }); }); } @@ -103,4 +103,4 @@ function umbracoMenuActions($q, treeService, $location, navigationService, appSt }; } -angular.module('umbraco.services').factory('umbracoMenuActions', umbracoMenuActions); \ No newline at end of file +angular.module('umbraco.services').factory('umbracoMenuActions', umbracoMenuActions); 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..257d36af31 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,27 @@ 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) { + return mainTreeApi.reloadNode(node); + } + else { + return $q.reject(); } }, - - //TODO: This should return a promise + reloadSection: function(sectionAlias) { - if (mainTreeEventHandler) { - mainTreeEventHandler.clearCache({ section: sectionAlias }); - mainTreeEventHandler.load(sectionAlias); + if (mainTreeApi) { + mainTreeApi.clearCache({ section: sectionAlias }); + return mainTreeApi.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); + else { + return $q.reject(); } }, @@ -364,7 +265,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/tree.service.js b/src/Umbraco.Web.UI.Client/src/common/services/tree.service.js index 888a067a66..3528eaadd0 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 @@ -263,8 +298,14 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS if (args.node.children && args.node.children.length > 0) { args.node.expanded = true; args.node.hasChildren = true; - } - return data; + } + + //Since we've removed the children & reloaded them, we need to refresh the UI now because the tree node UI doesn't operate on normal angular $watch since that will be pretty slow + if (angular.isFunction(args.node.updateNodeData)) { + args.node.updateNodeData(args.node); + } + + return $q.when(data); }, function(reason) { @@ -277,7 +318,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS //tell notications about the error notificationsService.error(reason); - return reason; + return $q.reject(reason); }); }, @@ -475,8 +516,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 +528,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 +545,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; }, /** @@ -579,7 +615,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS .then(function (data) { //now that we have the data, we need to add the level property to each item and the view self._formatNodeDataForUseInUI(treeItem, data, section, treeItem.level + 1); - return data; + return $q.when(data); }); }, @@ -604,12 +640,10 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS throw "cannot reload a single node without an assigned node.section"; } - var deferred = $q.defer(); - //set the node to loading node.loading = true; - this.getChildren({ node: node.parent(), section: node.section }).then(function(data) { + return this.getChildren({ node: node.parent(), section: node.section }).then(function(data) { //ok, now that we have the children, find the node we're reloading var found = _.find(data, function(item) { @@ -632,17 +666,15 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS //set the node loading node.parent().children[index].loading = false; - //return - deferred.resolve(node.parent().children[index]); + //return + return $q.when(node.parent().children[index]); } else { - deferred.reject(); + return $q.reject(); } }, function() { - deferred.reject(); + return $q.reject(); }); - - return deferred.promise; }, /** @@ -696,8 +728,6 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS args.path.push("-1"); } - var deferred = $q.defer(); - //get the rootNode for the current node, we'll sync based on that var root = this.getTreeRoot(args.node); if (!root) { @@ -711,8 +741,7 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS if (String(args.path[currPathIndex]).toLowerCase() === String(args.node.id).toLowerCase()) { if (args.path.length === 1) { //return the root - deferred.resolve(root); - return deferred.promise; + return $q.when(root); } else { //move to the next path part and continue @@ -732,16 +761,12 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS if (args.path.length === (currPathIndex + 1)) { //woot! synced the node if (!args.forceReload) { - deferred.resolve(child); + return $q.when(child); } else { //even though we've found the node if forceReload is specified //we want to go update this single node from the server - self.reloadNode(child).then(function (reloaded) { - deferred.resolve(reloaded); - }, function () { - deferred.reject(); - }); + return self.reloadNode(child); } } else { @@ -749,46 +774,44 @@ function treeService($q, treeResource, iconHelper, notificationsService, eventsS currPathIndex++; node = child; //recurse - doSync(); + return doSync(); } } else { //couldn't find it in the - self.loadNodeChildren({ node: node, section: node.section }).then(function () { + return self.loadNodeChildren({ node: node, section: node.section }).then(function () { //ok, got the children, let's find it var found = self.getChildNode(node, args.path[currPathIndex]); if (found) { if (args.path.length === (currPathIndex + 1)) { //woot! synced the node - deferred.resolve(found); + return $q.when(found); } else { //now we need to recurse with the updated node/currPathIndex currPathIndex++; node = found; //recurse - doSync(); + return doSync(); } } else { //fail! - deferred.reject(); + return $q.reject(); } }, function () { //fail! - deferred.reject(); + return $q.reject(); }); } }; //start - doSync(); - - return deferred.promise; + return doSync(); } }; } -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/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..b1810ca683 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -9,18 +9,113 @@ * * @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) { - //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 = {}; - //Put the navigation service on this scope so we can use it's methods/properties in the view. + //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); + }); + + //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 (n.section) { + $location.path(n.section).search(""); + } + + navigationService.hideNavigation(); + }); + + //once this is wired up, the nav is ready + eventsService.emit("app.navigationReady", { treeApi: $scope.treeApi}); + } + + //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; @@ -37,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 () { @@ -137,32 +236,86 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, languageResource.getAll().then(function(languages) { $scope.languages = languages; - // select the default language - $scope.languages.forEach(function(language) { - if(language.isDefault) { - $scope.selectLanguage(language); + // make the default language selected + $scope.languages.forEach(function (language) { + if (language.isDefault) { + $scope.selectedLanguage = language; } }); - }); })); - $scope.selectLanguage = function(language, languages) { + /** + * 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) { $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 + + //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 () { + + //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 })); + } + //TODO: If we want to keep all paths expanded ... but we need more testing since we need to deal with unexpanding + //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); + }); + }); + }; //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..7fb35a4cd0 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -1,31 +1,32 @@ /** 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) { - - assetsService._loadInitAssets().then(function() { + eventsService.on("app.authenticated", function (evt, data) { - // Loads the user's locale settings for Moment. - userService.loadMomentLocaleForCurrentUser().then(function() { + assetsService._loadInitAssets().then(function() { + $q.all([ + userService.loadMomentLocaleForCurrentUser(), + tourService.registerAllTours() + ]).then(function () { //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 @@ -34,7 +35,8 @@ app.run(['userService', '$log', '$rootScope', '$location', 'queryStrings', 'navi } }); - }, function(){ + }, function () { + appAuthenticated = true; appReady(data); }); }); @@ -50,7 +52,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 +61,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 +69,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 +97,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 +113,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/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/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 2faf4ebaa5..dec40440f2 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,10 +23,13 @@ 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; - 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; @@ -61,11 +64,18 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", vm.closeMiniListView = closeMiniListView; vm.selectListViewNode = selectListViewNode; + function initDialogTree() { + vm.dialogTreeApi.callbacks.treeLoaded(treeLoadedHandler); + //TODO: Also deal with unexpanding!! + 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; @@ -97,14 +107,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); } @@ -188,14 +192,35 @@ 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 + + //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 () { + + //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 })); + } + //execute them sequentially + angularHelper.executeSequentialPromises(promises); + }); + }); }; function toggleLanguageSelector() { vm.languageSelectorIsOpen = !vm.languageSelectorIsOpen; }; - - function nodeExpandedHandler(ev, args) { + + function nodeExpandedHandler(args) { + + //store the reference to the expanded node path + if (args.node) { + treeService._trackExpandedPaths(args.node, expandedPaths); + } // open mini list view for list views if (args.node.metaData.isContainer) { @@ -225,7 +250,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; @@ -233,7 +258,7 @@ angular.module("umbraco").controller("Umbraco.Overlays.TreePickerController", } //wires up selection - function nodeSelectHandler(ev, args) { + function nodeSelectHandler(args) { args.event.preventDefault(); args.event.stopPropagation(); @@ -578,17 +603,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..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,11 +16,13 @@ -
+
+ cachekey="{{treeCacheKey}}" + api="treeApi" + on-init="onTreeInit()" + section="{{currentSection}}" + customtreeparams="{{customTreeParams}}">
@@ -49,4 +51,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 385ebffca3..3618a12480 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -216,13 +216,6 @@ sort.aspx ASPXCodeBehind - - publish.aspx - ASPXCodeBehind - - - publish.aspx - default.Master ASPXCodeBehind @@ -406,17 +399,7 @@ - - - - - - - - - - @@ -454,10 +437,6 @@ - - - - @@ -490,7 +469,6 @@ - @@ -613,7 +591,6 @@ Form - diff --git a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml index 84a08de319..549954bfc1 100644 --- a/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/Views/AuthorizeUpgrade.cshtml @@ -11,6 +11,7 @@ @using Umbraco.Web @using Umbraco.Web.Editors @using umbraco +@using Umbraco.Core.Configuration @inherits System.Web.Mvc.WebViewPage @{ 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) - - - - - -
- -
-

- <%= 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/Editors/BackOfficeController.cs b/src/Umbraco.Web/Editors/BackOfficeController.cs index 3307c373a6..1988808d23 100644 --- a/src/Umbraco.Web/Editors/BackOfficeController.cs +++ b/src/Umbraco.Web/Editors/BackOfficeController.cs @@ -38,17 +38,6 @@ using JArray = Newtonsoft.Json.Linq.JArray; namespace Umbraco.Web.Editors { - public class BackOfficeModel - { - public BackOfficeModel(string path, UmbracoFeatures features) - { - Path = path; - Features = features; - } - - public string Path { get; } - public UmbracoFeatures Features { get; } - } /// /// Represents a controller user to render out the default back office view and JS results. @@ -85,8 +74,8 @@ namespace Umbraco.Web.Editors public async Task Default() { return await RenderDefaultOrProcessExternalLoginAsync( - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(GlobalSettings.Path, _features)), - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(GlobalSettings.Path, _features))); + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings)), + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/Default.cshtml", new BackOfficeModel(_features, GlobalSettings))); } [HttpGet] @@ -159,7 +148,7 @@ namespace Umbraco.Web.Editors { return await RenderDefaultOrProcessExternalLoginAsync( //The default view to render when there is no external login info or errors - () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(GlobalSettings.Path, _features)), + () => View(GlobalSettings.Path.EnsureEndsWith('/') + "Views/AuthorizeUpgrade.cshtml", new BackOfficeModel(_features, GlobalSettings)), //The ActionResult to perform if external login is successful () => Redirect("/")); } diff --git a/src/Umbraco.Web/Editors/BackOfficeModel.cs b/src/Umbraco.Web/Editors/BackOfficeModel.cs new file mode 100644 index 0000000000..75a388ee80 --- /dev/null +++ b/src/Umbraco.Web/Editors/BackOfficeModel.cs @@ -0,0 +1,17 @@ +using Umbraco.Core.Configuration; +using Umbraco.Web.Features; + +namespace Umbraco.Web.Editors +{ + public class BackOfficeModel + { + public BackOfficeModel(UmbracoFeatures features, IGlobalSettings globalSettings) + { + Features = features; + GlobalSettings = globalSettings; + } + + public UmbracoFeatures Features { get; } + public IGlobalSettings GlobalSettings { get; } + } +} diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs index 60ef3cf529..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"); @@ -211,7 +212,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/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(); } 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 145c0ad08b..923078c0b7 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -123,6 +123,7 @@ + @@ -1253,33 +1254,6 @@ Code - - delete.aspx - ASPXCodeBehind - - - delete.aspx - - - editContent.aspx - ASPXCodeBehind - - - editContent.aspx - - - preview.aspx - ASPXCodeBehind - - - preview.aspx - - - publish.aspx - - - publish.aspx - @@ -1471,13 +1445,6 @@ EditDictionaryItem.aspx - - editLanguage.aspx - ASPXCodeBehind - - - editLanguage.aspx - Code @@ -1624,7 +1591,6 @@ ASPXCodeBehind - Form @@ -1649,12 +1615,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;