diff --git a/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js b/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js index 938edb5419..8160dfccea 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/appstate.service.js @@ -16,8 +16,7 @@ function appState($rootScope) { touchDevice: null, showTray: null, stickyNavigation: null, - navMode: null, - editingEntity: null + navMode: null }; var sectionState = { @@ -200,14 +199,28 @@ angular.module('umbraco.services').factory('appState', appState); * * it is possible to modify this object, so should be used with care */ -angular.module('umbraco.services').factory("editorState", function(){ - return { - //we need this structure to return as an object reference - current: {entity: null}, +angular.module('umbraco.services').factory("editorState", function() { - //shortcut to current.entity = whatever; - set: function(entity){ - this.current.entity = entity; + var current = null; + var state = { + set: function (entity) { + current = entity; + }, + reset: function() { + current = null; } + }; + + //create a get/set property but don't allow setting + Object.defineProperty(state, "current", { + get: function () { + return current; + }, + set: function (value) { + throw "Use editorState.set to set the value of the current entity"; + }, + }); + + return state; }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index 0811d5b650..34fc1b5888 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -1,6 +1,6 @@ /** Executed when the application starts */ -app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', - function(userService, $log, $rootScope, $location, navigationService, appState) { +app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', 'editorState', + function(userService, $log, $rootScope, $location, navigationService, appState, editorState) { var firstRun = true; @@ -18,10 +18,14 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', if(current.params.section){ $rootScope.locationTitle = current.params.section + " - " + $location.$$host; - }else{ + } + else { $rootScope.locationTitle = "Umbraco - " + $location.$$host; } + //reset the editorState on each successful route chage + editorState.reset(); + }); /** When the route change is rejected - based on checkAuth - we'll prevent the rejected route from executing including diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js index 6789ab3879..5d1bba3017 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.edit.controller.js @@ -124,8 +124,7 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); - //update appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); configureButtons(data); @@ -143,8 +142,7 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); - //update appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); deferred.reject(err); }); @@ -162,8 +160,7 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS .then(function(data) { $scope.loaded = true; $scope.content = data; - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); configureButtons($scope.content); @@ -175,9 +172,7 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS .then(function(data) { $scope.loaded = true; $scope.content = data; - - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); configureButtons($scope.content); @@ -210,6 +205,8 @@ function ContentEditController($scope, $routeParams, $q, $timeout, $window, appS rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); + editorState.set($scope.content); + configureButtons(data); navigationService.syncTree({ tree: "content", path: data.path.split(","), forceReload: true }).then(function (syncArgs) { diff --git a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js index e34d9554ae..a2a96e9e9f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/datatype/datatype.edit.controller.js @@ -64,11 +64,11 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig $scope.preValuesLoaded = true; $scope.content = data; - //share state - editorState.set($scope.content); - createPreValueProps($scope.content.preValues); + //share state + editorState.set($scope.content); + //in one particular special case, after we've created a new item we redirect back to the edit // route but there might be server validation errors in the collection which we need to display // after the redirect, so we will bind all subscriptions which will show the server validation errors @@ -92,6 +92,9 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig $scope.preValuesLoaded = true; $scope.content.preValues = data; createPreValueProps($scope.content.preValues); + + //share state + editorState.set($scope.content); }); } }); @@ -113,6 +116,9 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig } }); + //share state + editorState.set($scope.content); + navigationService.syncTree({ tree: "datatype", path: [String(data.id)], forceReload: true }).then(function (syncArgs) { $scope.currentNode = syncArgs.node; }); @@ -125,6 +131,9 @@ function DataTypeEditController($scope, $routeParams, $location, appState, navig redirectOnFailure: false, err: err }); + + //share state + editorState.set($scope.content); }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js index 896edb13b7..ab9da21733 100644 --- a/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/media/media.edit.controller.js @@ -20,8 +20,6 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi $scope.loaded = true; $scope.content = data; - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); editorState.set($scope.content); }); } @@ -30,8 +28,7 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi .then(function (data) { $scope.loaded = true; $scope.content = data; - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); //in one particular special case, after we've created a new item we redirect back to the edit @@ -62,8 +59,7 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); - //update appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); navigationService.syncTree({ tree: "media", path: data.path, forceReload: true }).then(function (syncArgs) { $scope.currentNode = syncArgs.node; @@ -77,8 +73,7 @@ function mediaEditController($scope, $routeParams, appState, mediaResource, navi rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); - //update appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); }); } diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js index 9715877d56..7fc78b67b2 100644 --- a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js @@ -31,8 +31,6 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS $scope.loaded = true; $scope.content = data; - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); editorState.set($scope.content); }); } @@ -41,8 +39,7 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS .then(function (data) { $scope.loaded = true; $scope.content = data; - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); }); } @@ -67,8 +64,7 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS $scope.loaded = true; $scope.content = data; - //put this into appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); var path = buildTreePath(data); @@ -103,8 +99,7 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, data) }); - //update appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); var path = buildTreePath(data); @@ -120,8 +115,7 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS rebindCallback: contentEditingHelper.reBindChangedProperties($scope.content, err.data) }); - //update appState - appState.setGlobalState("editingEntity", umbModelMapper.convertToEntityBasic($scope.content)); + editorState.set($scope.content); }); } diff --git a/src/Umbraco.Web.UI.Client/test/unit/common/services/app-state.spec.js b/src/Umbraco.Web.UI.Client/test/unit/common/services/app-state.spec.js index 69a0e08b88..749bbca3de 100644 --- a/src/Umbraco.Web.UI.Client/test/unit/common/services/app-state.spec.js +++ b/src/Umbraco.Web.UI.Client/test/unit/common/services/app-state.spec.js @@ -1,13 +1,32 @@ describe('appState tests', function () { - var appState, $rootScope; + var appState, $rootScope, editorState; beforeEach(module('umbraco.services')); beforeEach(inject(function ($injector) { appState = $injector.get('appState'); $rootScope = $injector.get('$rootScope'); + editorState = $injector.get('editorState'); })); + describe('Editor state', function () { + it('Can set', function () { + editorState.set({ some: "object" }); + expect(editorState.current).not.toBeNull(); + expect(editorState.current.some).toBe("object"); + }); + it('Can reset', function () { + editorState.reset(); + expect(editorState.current).toBeNull(); + }); + it('Throws when setting current', function () { + function setCurrent() { + editorState.current = { some: "object" }; + } + expect(setCurrent).toThrow(); + }); + }); + describe('Global state', function () { it('Can get/set state', function () { appState.setGlobalState("showNavigation", true); diff --git a/src/Umbraco.Web.UI/umbraco/js/init.js b/src/Umbraco.Web.UI/umbraco/js/init.js index 0811d5b650..34fc1b5888 100644 --- a/src/Umbraco.Web.UI/umbraco/js/init.js +++ b/src/Umbraco.Web.UI/umbraco/js/init.js @@ -1,6 +1,6 @@ /** Executed when the application starts */ -app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', - function(userService, $log, $rootScope, $location, navigationService, appState) { +app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', 'editorState', + function(userService, $log, $rootScope, $location, navigationService, appState, editorState) { var firstRun = true; @@ -18,10 +18,14 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', if(current.params.section){ $rootScope.locationTitle = current.params.section + " - " + $location.$$host; - }else{ + } + else { $rootScope.locationTitle = "Umbraco - " + $location.$$host; } + //reset the editorState on each successful route chage + editorState.reset(); + }); /** When the route change is rejected - based on checkAuth - we'll prevent the rejected route from executing including