diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js index 15f95b2a60..6fb6f0156d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/content/edit.controller.js @@ -21,7 +21,6 @@ $scope.page.listViewPath = null; $scope.page.isNew = $scope.isNew ? true : false; $scope.page.buttonGroupState = "init"; - $scope.page.culture = $scope.culture; $scope.page.hideActionsMenu = infiniteMode ? true : false; $scope.page.hideChangeVariant = infiniteMode ? true : false; $scope.allowOpen = true; @@ -56,39 +55,68 @@ bindEvents(); // set first app to active + // TODO: We need to track active $scope.content.apps[0].active = true; + setActiveCulture(); + } + + /** + * The content item(s) are loaded into an array and this will set the active content item based on the current culture. + * If the content item is invariant, then only one item exists in the array. + */ + function setActiveCulture() { // set the active variant - var activeCultureSet = false; + var activeVariant = null; _.each($scope.content.variants, function (v) { - if (!activeCultureSet) { - if (v.language.culture === $scope.page.culture) { - v.active = true; - $scope.content.currentVariant = v; - activeCultureSet = true; - } + if (v.language.culture === $scope.culture) { + v.active = true; + activeVariant = v; + } + else { + v.active = false; } }); - if (!activeCultureSet) { + if (!activeVariant) { // set the first variant to active $scope.content.variants[0].active = true; - $scope.content.currentVariant = $scope.content.variants[0]; - } + activeVariant = $scope.content.variants[0]; + } + + //If there are no editors yet then create one with the current content. + //if there's already a main editor then update it with the current content. + //The model that is assigned to the editor contains the current content variant along + //with a copy of the contentApps. This is required because each editor renders it's own + //content apps section and the content apps contains the view for editing content itself + //and we need to assign a view model to the subView so that it is scoped to the current + //editor so that split views work. This is a bit hacky but it's required because the content + //app stuff isn't built to have a scoped model to an editor, it's built to have a single global + //model but that doesn't work for having split view. + + if (!activeVariant.apps) { + //copy from the main model + activeVariant.apps = angular.copy($scope.content.apps); + } + + //the assign the activeVariant to a view model to the content app + var contentApp = _.find(activeVariant.apps, function (a) { + return a.alias === "content"; + }); + contentApp.viewModel = activeVariant; - // create new editor for split view if ($scope.editors.length === 0) { var editor = { - content: $scope.content + content: activeVariant }; $scope.editors.push(editor); } else if ($scope.editors.length === 1) { - $scope.editors[0].content = $scope.content; + $scope.editors[0].content = activeVariant; } else { //fixme - need to fix something here if we are re-loading a content item that is in a split view } - } + } function bindEvents() { //bindEvents can be called more than once and we don't want to have multiple bound events @@ -487,7 +515,21 @@ $scope.openInSplitView = function (selectedVariant) { - console.log(selectedVariant); + //only the content app can be selected since no other apps are shown, and because we copy all of these apps + //to the "editors" we need to update this across all editors + for (var e = 0; e < $scope.editors.length; e++) { + var editor = $scope.editors[e]; + for (var i = 0; i < editor.content.apps.length; i++) { + var app = editor.content.apps[i]; + if (app.alias === "content") { + app.active = true; + } + else { + app.active = false; + } + } + } + var editor = {}; // hacking animation states - these should hopefully be easier to do when we upgrade angular @@ -575,6 +617,12 @@ } }; + $scope.$watch('culture', function (newVal, oldVal) { + if (newVal !== oldVal) { + setActiveCulture(); + } + }); + //ensure to unregister from all events! $scope.$on('$destroy', function () { for (var e in evts) { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js index a0d38667bf..3e318982f1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorheader.directive.js @@ -201,7 +201,7 @@ Use this directive to construct a header inside the main editor window. **/ -(function() { +(function () { 'use strict'; function EditorHeaderDirective(iconHelper, $location, editorService) { @@ -213,17 +213,17 @@ Use this directive to construct a header inside the main editor window. scope.vm.currentVariant = ""; function onInit() { - setCurrentVariant(scope.variants); + setCurrentVariant(); } - function setCurrentVariant(variants) { - angular.forEach(variants, function (variant) { - if(variant.active) { + function setCurrentVariant() { + angular.forEach(scope.variants, function (variant) { + if (variant.active) { scope.vm.currentVariant = variant; } }); } - + scope.goBack = function () { if (scope.onBack) { scope.onBack(); @@ -235,11 +235,11 @@ Use this directive to construct a header inside the main editor window. $location.search("cculture", variant.language.culture); }; - scope.openIconPicker = function() { + scope.openIconPicker = function () { var iconPicker = { icon: scope.icon.split(' ')[0], color: scope.icon.split(' ')[1], - submit: function(model) { + submit: function (model) { if (model.icon) { if (model.color) { scope.icon = model.icon + " " + model.color; @@ -251,35 +251,44 @@ Use this directive to construct a header inside the main editor window. } editorService.close(); }, - close: function() { + close: function () { editorService.close(); } }; editorService.iconPicker(iconPicker); }; - scope.closeSplitView = function() { - if(scope.onCloseSplitView) { + scope.closeSplitView = function () { + if (scope.onCloseSplitView) { scope.onCloseSplitView(); } }; - scope.openInSplitView = function(event, variant) { - if(scope.onOpenInSplitView) { + scope.openInSplitView = function (event, variant) { + if (scope.onOpenInSplitView) { scope.vm.dropdownOpen = false; - scope.onOpenInSplitView({"variant": variant}); + scope.onOpenInSplitView({ "variant": variant }); } }; - //TODO: Change this, we cannot watch the whole model - //scope.$watch('variants', function(newValue, oldValue){ - // if(!newValue) return; - // if(newValue === oldValue) return; - // setCurrentVariant(newValue); - //}, true); - onInit(); + //watch for the active culture changing, if it changes, update the current variant + if (scope.variants) { + scope.$watch(function () { + for (var i = 0; i < scope.variants.length; i++) { + var v = scope.variants[i]; + if (v.active) { + return v.language.culture; + } + } + return scope.vm.currentVariant.language.culture; //should never get here + }, function (newValue, oldValue) { + if (newValue !== scope.vm.currentVariant.language.culture) { + setCurrentVariant(); + } + }); + } } var directive = { diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorsubviews.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorsubviews.directive.js index db0dad8de7..ea3c4799cd 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorsubviews.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/components/editor/umbeditorsubviews.directive.js @@ -1,48 +1,26 @@ -(function() { - 'use strict'; +(function () { + 'use strict'; - function EditorSubViewsDirective() { + function EditorSubViewsDirective() { - function link(scope, el, attr, ctrl) { + function link(scope, el, attr, ctrl) { - scope.activeView = {}; + } - // set toolbar from selected navigation item - function setActiveView(items) { + var directive = { + restrict: 'E', + replace: true, + templateUrl: 'views/components/editor/umb-editor-sub-views.html', + scope: { + subViews: "=", + model: "=" + }, + link: link + }; - for (var index = 0; index < items.length; index++) { + return directive; + } - var item = items[index]; - - if (item.active && item.view) { - scope.activeView = item; - } - } - } - - // watch for navigation changes - scope.$watch('subViews', function(newValue, oldValue) { - if (newValue) { - setActiveView(newValue); - } - }, true); - - } - - var directive = { - restrict: 'E', - replace: true, - templateUrl: 'views/components/editor/umb-editor-sub-views.html', - scope: { - subViews: "=", - model: "=" - }, - link: link - }; - - return directive; - } - - angular.module('umbraco.directives').directive('umbEditorSubViews', EditorSubViewsDirective); + angular.module('umbraco.directives').directive('umbEditorSubViews', EditorSubViewsDirective); })(); diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index 6e444cbf84..fb6fadb444 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -43,7 +43,9 @@ app.run(['userService', '$q', '$log', '$rootScope', '$route', '$location', 'urlH } var currentRouteParams = null; - var globalQueryStrings = ["mculture"]; + + //A list of query strings defined that when changed will not cause a reload of the route + var nonRoutingQueryStrings = ["mculture", "cculture"]; /** execute code on each successful route */ $rootScope.$on('$routeChangeSuccess', function (event, current, previous) { @@ -131,15 +133,17 @@ app.run(['userService', '$q', '$log', '$rootScope', '$route', '$location', 'urlH var allowRoute = true; - //the only time that we want to cancel is if any of the globalQueryStrings have changed - //in which case the number of parts need to be equal before comparing values - if (_.keys(currUrlParts).length == _.keys(nextUrlParts).length) { + //The only time that we want to cancel is if only any of the nonRoutingQueryStrings have changed/added. + //If any of the other parts have changed we do not cancel + var currRoutingKeys = _.difference(_.keys(currUrlParts), nonRoutingQueryStrings); + var nextRoutingKeys = _.difference(_.keys(nextUrlParts), nonRoutingQueryStrings); + var diff = _.difference(currRoutingKeys, nextRoutingKeys); + //if the routing parameter keys are the same, we'll compare their values to see if any have changed and if so then the routing will be allowed. + if (diff.length == 0) { var partsChanged = 0; - _.each(currUrlParts, function (value, key) { - if (globalQueryStrings.indexOf(key) === -1) { - if (value.toLowerCase() !== nextUrlParts[key].toLowerCase()) { - partsChanged++; - } + _.each(currRoutingKeys, function (k) { + if (currUrlParts[k] != nextUrlParts[k]) { + partsChanged++; } }); if (partsChanged === 0) { diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index d41427c203..be65dffd48 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -161,7 +161,7 @@ app.config(function ($routeProvider) { .when('/:section/:tree/:method?/:id', { //This allows us to dynamically change the template for this route since you cannot inject services into the templateUrl method. template: "
", - //This controller will execute for this route, then we replace the template dynamnically based on the current tree. + //This controller will execute for this route, then we replace the template dynamically based on the current tree. controller: function ($scope, $route, $routeParams, treeService) { if (!$routeParams.tree || !$routeParams.method) { diff --git a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html index bf89bf2fe9..a437f3b6a7 100644 --- a/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html +++ b/src/Umbraco.Web.UI.Client/src/views/components/content/edit.html @@ -17,12 +17,12 @@