From ee386d06dac1555f8bafcbebd754f30e8ec44e71 Mon Sep 17 00:00:00 2001 From: Jeavon Leopold Date: Wed, 1 Oct 2014 18:48:23 +0100 Subject: [PATCH 01/51] Fix for U4-5480 "Bad value for attribute rel on element img in Richtext editor" by removing the attributes in the RTE value converter so they don't render on the front end site but still exist in the Umbraco UI --- .../RteMacroRenderingValueConverter.cs | 60 ++++++++++++++++--- 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs index 548d4357db..d37ec518c7 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs @@ -11,6 +11,10 @@ using Umbraco.Web.Templates; namespace Umbraco.Web.PropertyEditors.ValueConverters { + using System.Linq; + + using HtmlAgilityPack; + /// /// A value converter for TinyMCE that will ensure any macro content is rendered properly even when /// used dynamically. @@ -58,18 +62,60 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters return sb.ToString(); } - public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) - { - if (source == null) return null; - var sourceString = source.ToString(); + public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) + { + if (source == null) + { + return null; + } + + var sourceString = source.ToString(); // ensures string is parsed for {localLink} and urls are resolved correctly sourceString = TemplateUtilities.ParseInternalLinks(sourceString, preview); - sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString); + sourceString = TemplateUtilities.ResolveUrlsFromTextString(sourceString); + // ensure string is parsed for macros and macros are executed correctly sourceString = RenderRteMacros(sourceString, preview); - return sourceString; - } + // find and remove the rel attributes used in the Umbraco UI from img tags + var doc = new HtmlDocument(); + doc.LoadHtml(sourceString); + + if (!doc.ParseErrors.Any() && doc.DocumentNode != null) + { + // Find all images with rel attribute + var imgNodes = doc.DocumentNode.SelectNodes("//img[@rel]"); + + if (imgNodes != null) + { + var modified = false; + + foreach (var img in imgNodes) + { + var firstOrDefault = img.Attributes.FirstOrDefault(x => x.Name == "rel"); + if (firstOrDefault != null) + { + var rel = firstOrDefault.Value; + + // Check that the rel attribute is a integer before removing + int nodeId; + if (int.TryParse(rel, out nodeId)) + { + img.Attributes.Remove("rel"); + modified = true; + } + } + } + + if (modified) + { + return doc.DocumentNode.OuterHtml; + } + } + } + + return sourceString; + } } } \ No newline at end of file From 562367e9a2fa67b707b98b0213e0f9229c9f8694 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 16 Dec 2014 15:25:13 +0000 Subject: [PATCH 02/51] Label on files not just folders --- .../src/less/property-editors.less | 37 +++++++++++-------- .../directives/html/umb-photo-folder.html | 8 ++-- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 1aea07bfbd..51319a5bf5 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -25,7 +25,7 @@ } .umb-codeeditor{ - width: 99%; + width: 99%; } // @@ -68,7 +68,7 @@ div.umb-codeeditor .umb-btn-toolbar { .mce-ico{font-size: 12px !important; color: @blackLight !important;} /* Special case to support helviticons for the tiny mce button controls */ .mce-ico.mce-i-custom[class^="icon-"], -.mce-ico.mce-i-custom[class*=" icon-"] { +.mce-ico.mce-i-custom[class*=" icon-"] { font-family: icomoon; font-size:16px !important; } @@ -100,8 +100,8 @@ ul.color-picker li a { /* pre-value editor */ .control-group.color-picker-preval pre { - display: inline; - margin-right: 20px; + display: inline; + margin-right: 20px; margin-left: 10px; } @@ -116,8 +116,8 @@ ul.color-picker li a { // -------------------------------------------------- .umb-mediapicker .add-link{ display: inline-block; - height: 120px; - width: 120px; + height: 120px; + width: 120px; text-align: center; color: @grayLight; border: 2px @grayLight dashed !important; @@ -187,7 +187,7 @@ ul.color-picker li a { .umb-sortable-thumbnails li img { - max-width:100%; + max-width:100%; max-height:100%; margin:auto; display:block; @@ -206,12 +206,12 @@ ul.color-picker li a { .umb-sortable-thumbnails .icon-holder * { color: @grayLight; - display: block + display: block } // -// Cropper +// Cropper // ------------------------------------------------- .umb-cropper{ @@ -237,7 +237,7 @@ ul.color-picker li a { position: relative; margin: auto; } - + .umb-cropper-gravity .viewport{ overflow: hidden; position: relative; @@ -301,8 +301,8 @@ ul.color-picker li a { // -------------------------------------------------- .umb-folderbrowser .add-link{ display: inline-block; - height: 120px; - width: 120px; + height: 120px; + width: 120px; text-align: center; border: 1px @grayLight dashed; line-height: 120px @@ -364,7 +364,7 @@ ul.color-picker li a { -.umb-photo-folder .picrow div a:first-child { +.umb-photo-folder .picrow div a:first-child { width:100%; height:100%; } @@ -375,6 +375,12 @@ ul.color-picker li a { background-color: @grayLighter; } +.umb-photo-folder .picrow div.umb-photo .umb-photo-img-name{ + overflow: hidden; + text-overlow: ellipsis; + white-space: no-wrap; +} + .umb-photo-folder a:hover{text-decoration: none} .umb-photo-folder .umb-non-thumbnail{ text-align: center; @@ -386,7 +392,8 @@ ul.color-picker li a { } //this is a temp hack, to provide selectors in the dialog: -.umb-photo-folder .pic:hover .selector-overlay{ +.umb-photo-folder .pic:hover .selector-overlay, +.umb-photo-folder .picrow div.umb-photo .umb-photo-img-name{ position: absolute; bottom: 0px; left: 0px; @@ -501,4 +508,4 @@ ul.color-picker li a { // -------------------------------------------------- .bootstrap-datetimepicker-widget .btn{padding: 0;} .bootstrap-datetimepicker-widget .picker-switch .btn{ background: none; border: none;} -.umb-datepicker .input-append .add-on{cursor: pointer;} \ No newline at end of file +.umb-datepicker .input-append .add-on{cursor: pointer;} diff --git a/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html b/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html index 8b0ced6ebe..00382a0a3e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html +++ b/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html @@ -13,11 +13,13 @@ {{img.name}} - -
+ +
+ {{img.name}} +
- Select From 3ea16e66d4c4440d2efd717d09508d09c777fe86 Mon Sep 17 00:00:00 2001 From: redmorello Date: Thu, 18 Dec 2014 11:07:08 +0000 Subject: [PATCH 03/51] Update forms.less Removed negative left margin from input and radio button inputs. --- src/Umbraco.Web.UI.Client/src/less/forms.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index 363a43203b..66da7a1f61 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -305,7 +305,7 @@ textarea { .radio input[type="radio"], .checkbox input[type="checkbox"] { float: left; - margin-left: -20px; + margin-left: 0px; } // Move the options list down to align with labels From e5ec9351287a1d9c9e1945bc598c371b6ff8faeb Mon Sep 17 00:00:00 2001 From: redmorello Date: Thu, 18 Dec 2014 11:08:44 +0000 Subject: [PATCH 04/51] Update forms.less Removed negative left margin from checkbox and radio button inputs. --- src/Umbraco.Web.UI.Client/lib/bootstrap/less/forms.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/lib/bootstrap/less/forms.less b/src/Umbraco.Web.UI.Client/lib/bootstrap/less/forms.less index 69bd7f6f88..2bfb88e7a0 100644 --- a/src/Umbraco.Web.UI.Client/lib/bootstrap/less/forms.less +++ b/src/Umbraco.Web.UI.Client/lib/bootstrap/less/forms.less @@ -229,7 +229,7 @@ textarea { .radio input[type="radio"], .checkbox input[type="checkbox"] { float: left; - margin-left: -20px; + margin-left: 0px; } // Move the options list down to align with labels From b8097219fb4472bbbb50a79f3b018d33ea5e5b5b Mon Sep 17 00:00:00 2001 From: Aaron Powell Date: Sun, 21 Dec 2014 17:56:33 +1100 Subject: [PATCH 05/51] Implementing a test for U4-6035 --- src/Umbraco.Tests/Models/ContentTests.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index dfaaae1d27..dde3d4854a 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -703,6 +703,25 @@ namespace Umbraco.Tests.Models Assert.That(contentType.WasPropertyDirty("Alias"), Is.True); } + [Test] + public void After_Committing_Changes_Was_Dirty_Is_True_On_Changed_Property() + { + // Arrange + var contentType = MockedContentTypes.CreateTextpageContentType(); + contentType.ResetDirtyProperties(); //reset + var content = MockedContent.CreateTextpageContent(contentType, "test", -1); + content.ResetDirtyProperties(); + + // Act + content.SetPropertyValue("title", "new title"); + content.ResetDirtyProperties(); //this would be like committing the entity + + // Assert + Assert.That(content.WasPropertyDirty("title"), Is.True); + Assert.That(content.Properties["title"].IsDirty(), Is.False); + Assert.That(content.Properties["title"].WasDirty(), Is.True); + } + [Test] public void If_Not_Committed_Was_Dirty_Is_False() { From 83840ba6ddba86c6add52987dda8b4da1e64b2d7 Mon Sep 17 00:00:00 2001 From: bjarnef Date: Wed, 4 Feb 2015 21:55:19 +0100 Subject: [PATCH 06/51] U4-4507 - Make expand arrow in sections as a toggle I have made some suggestions, so the right arrow act as a toggle button, so you easily can collapse the extra overflow-sections. Furthermore I have made some changes, so when you click userDialog or helpDialog other open dialogs close and also sections. When you click a section or expand it also close dialogs, so you don't have to close those dialogs first. --- .../directives/umbsections.directive.js | 26 +++++++++++- .../src/common/services/navigation.service.js | 37 ++++++++++------- .../src/less/sections.less | 40 +++++++++++++++++-- .../views/common/dialogs/help.controller.js | 6 ++- .../src/views/common/dialogs/help.html | 2 +- .../src/views/directives/umb-sections.html | 2 +- 6 files changed, 90 insertions(+), 23 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js index 0b91cff44e..b98d0db49c 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js @@ -22,6 +22,9 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se if (scope.showTray) { return 'slide'; } + else if (scope.showTray === false) { + return 'slide'; + } else { return ''; } @@ -83,6 +86,13 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se }; scope.sectionClick = function (section) { + if (navigationService.userDialog) { + navigationService.userDialog.close(); + } + if (navigationService.helpDialog) { + navigationService.helpDialog.close(); + } + navigationService.hideSearch(); navigationService.showTree(section.alias); $location.path("/" + section.alias); @@ -92,8 +102,20 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se navigationService.reloadSection(section.alias); }; - scope.trayClick = function(){ - navigationService.showTray(); + scope.trayClick = function () { + // close dialogs + if (navigationService.userDialog) { + navigationService.userDialog.close(); + } + if (navigationService.helpDialog) { + navigationService.helpDialog.close(); + } + + if (appState.getGlobalState("showTray") === true) { + navigationService.hideTray(); + } else { + navigationService.showTray(); + } }; loadSections(); 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 4cfba513e5..ba4a4b1488 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 @@ -513,23 +513,26 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * Opens the user dialog, next to the sections navigation * template is located in views/common/dialogs/user.html */ - showUserDialog: function() { + showUserDialog: function () { + // hide tray and close help dialog + if (service.helpDialog) { + service.helpDialog.close(); + } + service.hideTray(); - if(userDialog){ - userDialog.close(); - userDialog = null; + if (service.userDialog) { + service.userDialog.close(); + service.userDialog = undefined; } - userDialog = dialogService.open( - { - template: "views/common/dialogs/user.html", - modalClass: "umb-modal-left", - show: true - }); - - + service.userDialog = dialogService.open( + { + template: "views/common/dialogs/user.html", + modalClass: "umb-modal-left", + show: true + }); - return userDialog; + return service.userDialog; }, /** @@ -541,7 +544,13 @@ function navigationService($rootScope, $routeParams, $log, $location, $q, $timeo * Opens the user dialog, next to the sections navigation * template is located in views/common/dialogs/user.html */ - showHelpDialog: function() { + showHelpDialog: function () { + // hide tray and close user dialog + service.hideTray(); + if (service.userDialog) { + service.userDialog.close(); + } + if(service.helpDialog){ service.helpDialog.close(); service.helpDialog = undefined; diff --git a/src/Umbraco.Web.UI.Client/src/less/sections.less b/src/Umbraco.Web.UI.Client/src/less/sections.less index f487165e98..795808f941 100644 --- a/src/Umbraco.Web.UI.Client/src/less/sections.less +++ b/src/Umbraco.Web.UI.Client/src/less/sections.less @@ -7,6 +7,7 @@ ul.sections { background: @blackLight; height: 100%; width: 80px; + border-right: 1px solid @grayDark; } ul.sections li { @@ -63,7 +64,7 @@ ul.sections:hover a span { // ------------------------- ul.sections li.avatar { - height: 69px; + height: 67px; padding: 30px 0 2px 0; text-align: center; margin: 0 0 0 -4px; @@ -116,7 +117,38 @@ ul.sections li.help a { // ------------------------- li.expand a, li.expand{border: none !Important;} -ul.sections-tray { - padding-top: 102px; - width: 80px; +li.expand { + + &.open > a > i.icon { + -webkit-transition: all 1s !important; + -o-transition: all 1s !important; + -moz-transition: all 1s !important; + transition: all 1s !important; + + &:before { + -ms-transform: rotate(180deg) !important; /* IE 9 */ + -webkit-transform: rotate(180deg) !important; /* Chrome, Safari, Opera */ + -o-transform: rotate(180deg) !important; + -moz-transform: rotate(180deg) !important; + transform: rotate(180deg) !important; + } + } +} + +ul.sections-tray { + padding-top: 99px; + width: 80px; + + & > li:first-child > a { + border-top: 1px solid #343434; + } + + & > li { + // 5px (instead of 4px) because of vertical border + border-left-width: 5px; + + &.current, &:hover { + border-left-width: 5px; + } + } } diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js index ae40a9a05d..95b7b8bbe5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js @@ -35,7 +35,11 @@ angular.module("umbraco") }); helpService.findVideos(rq).then(function(videos){ - $scope.videos = videos; + $scope.videos = videos; + + angular.forEach($scope.videos, function (obj) { + obj.thumbnail = obj.thumbnail.replace(/(\.[\w\d_-]+)$/i, '_thumb$1'); + }); }); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html index ef759c8b06..80ce8f80c0 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.html @@ -37,7 +37,7 @@
  • diff --git a/src/Umbraco.Web.UI.Client/src/views/directives/umb-sections.html b/src/Umbraco.Web.UI.Client/src/views/directives/umb-sections.html index 367b0e2b4b..94d235ee3a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/directives/umb-sections.html +++ b/src/Umbraco.Web.UI.Client/src/views/directives/umb-sections.html @@ -16,7 +16,7 @@ -
  • +
  • From a721f6836fb4a0317709f2d5061e97d662a28e53 Mon Sep 17 00:00:00 2001 From: bjarnef Date: Thu, 5 Feb 2015 03:31:41 +0100 Subject: [PATCH 07/51] Pointer cursor for sections in IE10 IE10 displayed a text cursor for tray and help section. Added cursor: pointer; to make sure a pointer cursor is displayed. --- src/Umbraco.Web.UI.Client/src/less/sections.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/sections.less b/src/Umbraco.Web.UI.Client/src/less/sections.less index 795808f941..9ba3855b60 100644 --- a/src/Umbraco.Web.UI.Client/src/less/sections.less +++ b/src/Umbraco.Web.UI.Client/src/less/sections.less @@ -43,6 +43,7 @@ ul.sections li a { width: 100%; height: 100%; margin: 0 0 0 -4px; + cursor: pointer; // make sure IE10 displays pointer cursor for expand and help sections. } ul.sections a span { From 7091cb60120862ffa60add119a628e7307a5c845 Mon Sep 17 00:00:00 2001 From: bjarnef Date: Thu, 5 Feb 2015 10:52:55 +0100 Subject: [PATCH 08/51] Change code for help videos Change code for in help.controller.js as it was. --- .../src/views/common/dialogs/help.controller.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js index 95b7b8bbe5..7fabd5c7df 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/help.controller.js @@ -36,10 +36,6 @@ angular.module("umbraco") helpService.findVideos(rq).then(function(videos){ $scope.videos = videos; - - angular.forEach($scope.videos, function (obj) { - obj.thumbnail = obj.thumbnail.replace(/(\.[\w\d_-]+)$/i, '_thumb$1'); - }); }); }); From 824212f6c9953f2648fae760a2db73c3ca6b97ee Mon Sep 17 00:00:00 2001 From: bjarnef Date: Sun, 15 Feb 2015 22:20:34 +0100 Subject: [PATCH 09/51] Keep headline at same position I made a small change to make sure the headline is in same position regardless it is editable or readonly. --- src/Umbraco.Web.UI.Client/src/less/panel.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index 7fc2d061ea..7c152cebae 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -48,6 +48,7 @@ background: none; margin: 15px 0 0 20px; padding: 3px 5px; + line-height: 1.4; height: auto; width: 100%; border: 1px solid @grayLighter; From 5579823b2d48d04b572425e34ac680101dc53e74 Mon Sep 17 00:00:00 2001 From: bjarnef Date: Mon, 16 Feb 2015 00:11:41 +0100 Subject: [PATCH 10/51] Remove padding-left from h1 in modal-left Removed left-padding from h1 in umb-modal-left to align it with the other text in the modal. --- src/Umbraco.Web.UI.Client/src/less/modals.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/modals.less b/src/Umbraco.Web.UI.Client/src/less/modals.less index dbfd4d7841..7e7aeb5c36 100644 --- a/src/Umbraco.Web.UI.Client/src/less/modals.less +++ b/src/Umbraco.Web.UI.Client/src/less/modals.less @@ -63,6 +63,7 @@ .umb-modal-left .umb-panel-header .umb-headline, .umb-modal-left .umb-panel-header h1 { width: auto; + padding-left: 0; } /* umb.dialog is used for the dialogs on the conent tree*/ From df5c5e78ffbd78de811f6ca22da9861cbc434dd4 Mon Sep 17 00:00:00 2001 From: bjarnef Date: Mon, 16 Feb 2015 20:58:40 +0100 Subject: [PATCH 11/51] Headline was cuttet off in Firefox In Firefox 35.0.1 the headline was cuttet off. The 1.4 line-height in commit 824212f6c9953f2648fae760a2db73c3ca6b97ee ensure the headline isn't cuttet off. However line-height: normal act as fallback as 1em it too little and cause the text might be cuttet off. --- src/Umbraco.Web.UI.Client/src/less/panel.less | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/less/panel.less b/src/Umbraco.Web.UI.Client/src/less/panel.less index 7c152cebae..4fed599ddc 100644 --- a/src/Umbraco.Web.UI.Client/src/less/panel.less +++ b/src/Umbraco.Web.UI.Client/src/less/panel.less @@ -92,7 +92,7 @@ margin: -6px 0 0 0; padding: 0 0 2px 0; border-radius: 0; - line-height: 1em; + line-height: normal; border: 1px solid transparent; color: @black; letter-spacing: -0.01em From dc3e14449392f595bbd58d8bbe6c5b4237b020ed Mon Sep 17 00:00:00 2001 From: kgiszewski Date: Mon, 20 Apr 2015 10:28:35 -0400 Subject: [PATCH 12/51] Fix for U4-6530 --- .../umbraco.presentation/umbraco/Trees/loadNodeTypes.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs index c64e78e9cf..8df83291fe 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadNodeTypes.cs @@ -46,6 +46,8 @@ namespace umbraco actions.Add(ActionExport.Instance); actions.Add(ContextMenuSeperator.Instance); actions.Add(ActionDelete.Instance); + actions.Add(ContextMenuSeperator.Instance); + actions.Add(ActionRefresh.Instance); } public override void RenderJS(ref StringBuilder Javascript) From 2f4ff6aaaebe389740cb9c5453065f97a8f0fc74 Mon Sep 17 00:00:00 2001 From: Allyen Date: Mon, 4 May 2015 11:49:07 +0200 Subject: [PATCH 13/51] Login redirect to originally requested URL --- src/Umbraco.Web.UI.Client/src/init.js | 2 ++ .../src/views/common/login.controller.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index f31e81e5d3..eb1bdfe2e8 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -44,6 +44,8 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', wiring up it's controller, etc... and then redirect to the rejected URL. */ $rootScope.$on('$routeChangeError', function(event, current, previous, rejection) { event.preventDefault(); + $rootScope.returnToPath = $location.$$path; + $rootScope.returnToSearch = $location.$$search; $location.path(rejection.path).search(rejection.search); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js index ad8fec63a9..59d8f6bf57 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js @@ -1,10 +1,10 @@ /** This controller is simply here to launch the login dialog when the route is explicitly changed to /login */ -angular.module('umbraco').controller("Umbraco.LoginController", function (eventsService, $scope, userService, $location) { +angular.module('umbraco').controller("Umbraco.LoginController", function (eventsService, $scope, userService, $location, $rootScope) { userService._showLoginDialog(); eventsService.on("app.ready", function(){ $scope.avatar = "assets/img/application/logo.png"; - $location.path("/").search(""); + $location.path($rootScope.returnToPath || "/").search($rootScope.returnToSearch || ""); }); }); \ No newline at end of file From 4144590189902e934cf87982f86af42b3c940916 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 5 May 2015 12:15:28 +0200 Subject: [PATCH 14/51] Upgrade to latest MySql.Data and loosen up NuGet dependency --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 2 +- src/Umbraco.Core/packages.config | 32 ++++++------ src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 2 +- src/Umbraco.Web.UI/packages.config | 50 +++++++++---------- src/umbraco.datalayer/packages.config | 6 +-- .../umbraco.datalayer.csproj | 2 +- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 8ce726d60e..e9f542c50e 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -26,7 +26,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 800842711d..bc272d351e 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -64,7 +64,7 @@ False - ..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll + ..\packages\MySql.Data.6.9.6\lib\net45\MySql.Data.dll False diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index f01b9e68ba..d717c88286 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -1,19 +1,19 @@  - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index ebecee3439..4a58e794a3 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -165,7 +165,7 @@ False - ..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll + ..\packages\MySql.Data.6.9.6\lib\net45\MySql.Data.dll False diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 283f7feb10..540f97fabb 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -1,28 +1,28 @@  - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/umbraco.datalayer/packages.config b/src/umbraco.datalayer/packages.config index 02379f5503..6c3f4c3945 100644 --- a/src/umbraco.datalayer/packages.config +++ b/src/umbraco.datalayer/packages.config @@ -1,6 +1,6 @@  - - - + + + \ No newline at end of file diff --git a/src/umbraco.datalayer/umbraco.datalayer.csproj b/src/umbraco.datalayer/umbraco.datalayer.csproj index e91df3acd0..1002075a03 100644 --- a/src/umbraco.datalayer/umbraco.datalayer.csproj +++ b/src/umbraco.datalayer/umbraco.datalayer.csproj @@ -78,7 +78,7 @@ False - ..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll + ..\packages\MySql.Data.6.9.6\lib\net45\MySql.Data.dll From 8299243129640b931eb664f1de17dcfa59bd216a Mon Sep 17 00:00:00 2001 From: Allyen Date: Tue, 5 May 2015 22:07:18 +0200 Subject: [PATCH 15/51] U4-6593 - After sort, reset the TinyMCE editors with previous settings --- .../propertyeditors/grid/grid.controller.js | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js index 883ba5483b..3ccbffcfa6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.controller.js @@ -14,6 +14,8 @@ angular.module("umbraco") // Sortable options // ********************************************* + var draggedRteSettings; + $scope.sortableOptions = { distance: 10, cursor: "move", @@ -40,15 +42,22 @@ angular.module("umbraco") }, start: function (e, ui) { + draggedRteSettings = {}; ui.item.find('.mceNoEditor').each(function () { - tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id')); + // remove all RTEs in the dragged row and save their settings + var id = $(this).attr('id'); + draggedRteSettings[id] = _.findWhere(tinyMCE.editors, { id: id }).settings; + tinyMCE.execCommand('mceRemoveEditor', false, id); }); }, stop: function (e, ui) { + // reset all RTEs affected by the dragging ui.item.parents(".usky-column").find('.mceNoEditor').each(function () { - tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id')); - tinyMCE.execCommand('mceAddEditor', false, $(this).attr('id')); + var id = $(this).attr('id'); + draggedRteSettings[id] = draggedRteSettings[id] || _.findWhere(tinyMCE.editors, { id: id }).settings; + tinyMCE.execCommand('mceRemoveEditor', false, id); + tinyMCE.init(draggedRteSettings[id]); }); } }; @@ -98,6 +107,7 @@ angular.module("umbraco") }, update: function (event, ui) { + // add all RTEs which are affected by the dragging if (!ui.sender) { if (cancelMove) { ui.item.sortable.cancel(); @@ -121,6 +131,11 @@ angular.module("umbraco") start: function (e, ui) { ui.item.find('.mceNoEditor').each(function () { notIncludedRte = []; + + // save the dragged RTE settings + draggedRteSettings = _.findWhere(tinyMCE.editors, { id: $(this).attr('id') }).settings; + + // remove the dragged RTE tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id')); }); }, @@ -128,14 +143,21 @@ angular.module("umbraco") stop: function (e, ui) { ui.item.parents(".usky-cell").find('.mceNoEditor').each(function () { if ($.inArray($(this).attr('id'), notIncludedRte) < 0) { + // add all dragged's neighbouring RTEs in the new cell notIncludedRte.splice(0, 0, $(this).attr('id')); } }); $timeout(function () { + // reconstruct the dragged RTE + tinyMCE.init(draggedRteSettings); + _.forEach(notIncludedRte, function (id) { - tinyMCE.execCommand('mceRemoveEditor', false, id); - tinyMCE.execCommand('mceAddEditor', false, id); - console.info("stop " + id); + // reset all the other RTEs + if (id != draggedRteSettings.id) { + var rteSettings = _.findWhere(tinyMCE.editors, { id: id }).settings; + tinyMCE.execCommand('mceRemoveEditor', false, id); + tinyMCE.init(rteSettings); + } }); }, 500, false); } From 7134373933c3c9988b8f5357b31def255b5911b8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 May 2015 13:25:24 +1000 Subject: [PATCH 16/51] Fixes: U4-6484 Don't cast to specific Examine types - only interfaces like ISearcher/IIndexer --- src/Umbraco.Web/Editors/EntityController.cs | 2 +- src/UmbracoExamine/XsltExtensions.cs | 18 ++---------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs index 4c1b8dd849..f197af32c1 100644 --- a/src/Umbraco.Web/Editors/EntityController.cs +++ b/src/Umbraco.Web/Editors/EntityController.cs @@ -340,7 +340,7 @@ namespace Umbraco.Web.Editors throw new NotSupportedException("The " + typeof(EntityController) + " currently does not support searching against object type " + entityType); } - var internalSearcher = (LuceneSearcher)ExamineManager.Instance.SearchProviderCollection[searcher]; + var internalSearcher = ExamineManager.Instance.SearchProviderCollection[searcher]; //build a lucene query: // the __nodeName will be boosted 10x without wildcards diff --git a/src/UmbracoExamine/XsltExtensions.cs b/src/UmbracoExamine/XsltExtensions.cs index 785a703b1c..abfe5cc555 100644 --- a/src/UmbracoExamine/XsltExtensions.cs +++ b/src/UmbracoExamine/XsltExtensions.cs @@ -32,7 +32,7 @@ namespace UmbracoExamine /// /// /// - internal static XPathNodeIterator Search(string searchText, bool useWildcards, LuceneSearcher provider, string indexType) + internal static XPathNodeIterator Search(string searchText, bool useWildcards, BaseSearchProvider provider, string indexType) { if (provider == null) throw new ArgumentNullException("provider"); @@ -50,9 +50,7 @@ namespace UmbracoExamine /// public static XPathNodeIterator Search(string searchText, bool useWildcards, string providerName, string indexType) { - EnsureProvider(ExamineManager.Instance.SearchProviderCollection[providerName]); - - var provider = ExamineManager.Instance.SearchProviderCollection[providerName] as LuceneSearcher; + var provider = ExamineManager.Instance.SearchProviderCollection[providerName]; return Search(searchText, useWildcards, provider, indexType); } @@ -190,18 +188,6 @@ namespace UmbracoExamine return SearchContentOnly(searchText, true); } - /// - /// Ensures the provider. - /// - /// The provider. - private static void EnsureProvider(BaseSearchProvider p) - { - if (!(p is LuceneSearcher)) - { - throw new NotSupportedException("XSLT Extensions are only support for providers of type LuceneSearcher"); - } - } - /// /// Gets the results as XML. /// From a51dd93ffe164ea14f4a55a0a93f36ac6ffbbefe Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 6 May 2015 08:58:45 +0200 Subject: [PATCH 17/51] Expressed version range was wrong --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index e9f542c50e..d54ffe5d3a 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -26,7 +26,7 @@ - + From 821daa82c4d4afc52637272015d45691d5adc0eb Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 May 2015 17:14:10 +1000 Subject: [PATCH 18/51] Fixes: U4-6474 Update to latest examine v0.1.63 --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 4 ++-- src/Umbraco.Tests/packages.config | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 6 +++--- src/Umbraco.Web.UI/packages.config | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 6 +++--- src/Umbraco.Web/packages.config | 2 +- src/UmbracoExamine/UmbracoExamine.csproj | 4 ++-- src/UmbracoExamine/packages.config | 2 +- src/umbraco.MacroEngines/packages.config | 2 +- src/umbraco.MacroEngines/umbraco.MacroEngines.csproj | 4 ++-- 11 files changed, 18 insertions(+), 18 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 8ce726d60e..9f0ad2e33f 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -32,7 +32,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 23a1e7788d..18b9b8d006 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -58,9 +58,9 @@ ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll - + False - ..\packages\Examine.0.1.62.2941\lib\Examine.dll + ..\packages\Examine.0.1.63.0\lib\Examine.dll False diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config index 7ae34de8c6..58d314c3b1 100644 --- a/src/Umbraco.Tests/packages.config +++ b/src/Umbraco.Tests/packages.config @@ -2,7 +2,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index ebecee3439..ae065504a3 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -126,9 +126,9 @@ False ..\packages\dotless.1.4.1.0\lib\dotless.Core.dll - - False - ..\packages\Examine.0.1.62.2941\lib\Examine.dll + + ..\packages\Examine.0.1.63.0\lib\Examine.dll + True False diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 283f7feb10..c839bdfc06 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -4,7 +4,7 @@ - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e5dd0ab2a0..08cf22ecd6 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -115,9 +115,9 @@ ..\packages\dotless.1.4.1.0\lib\dotless.Core.dll - - ..\packages\Examine.0.1.62.2941\lib\Examine.dll - True + + False + ..\packages\Examine.0.1.63.0\lib\Examine.dll False diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index e923c3aeea..315d780852 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/UmbracoExamine/UmbracoExamine.csproj b/src/UmbracoExamine/UmbracoExamine.csproj index 1922d86d88..b7fc35542a 100644 --- a/src/UmbracoExamine/UmbracoExamine.csproj +++ b/src/UmbracoExamine/UmbracoExamine.csproj @@ -82,9 +82,9 @@ ..\Solution Items\TheFARM-Public.snk - + False - ..\packages\Examine.0.1.62.2941\lib\Examine.dll + ..\packages\Examine.0.1.63.0\lib\Examine.dll False diff --git a/src/UmbracoExamine/packages.config b/src/UmbracoExamine/packages.config index caa69d63c4..efa216d153 100644 --- a/src/UmbracoExamine/packages.config +++ b/src/UmbracoExamine/packages.config @@ -1,6 +1,6 @@  - + \ No newline at end of file diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config index 525873f9e0..9951ba7e01 100644 --- a/src/umbraco.MacroEngines/packages.config +++ b/src/umbraco.MacroEngines/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj index 50709bc808..a34198b5ce 100644 --- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj +++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj @@ -45,9 +45,9 @@ false - + False - ..\packages\Examine.0.1.62.2941\lib\Examine.dll + ..\packages\Examine.0.1.63.0\lib\Examine.dll False From e8d4777d7420998d09a45c8b8adb1b503cec43ce Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 6 May 2015 17:36:46 +1000 Subject: [PATCH 19/51] re-formatted some of the PR --- .../ValueConverters/RteMacroRenderingValueConverter.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs index d37ec518c7..2802a4d631 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/RteMacroRenderingValueConverter.cs @@ -8,12 +8,11 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Web.Templates; +using System.Linq; +using HtmlAgilityPack; namespace Umbraco.Web.PropertyEditors.ValueConverters { - using System.Linq; - - using HtmlAgilityPack; /// /// A value converter for TinyMCE that will ensure any macro content is rendered properly even when @@ -82,7 +81,7 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters var doc = new HtmlDocument(); doc.LoadHtml(sourceString); - if (!doc.ParseErrors.Any() && doc.DocumentNode != null) + if (doc.ParseErrors.Any() == false && doc.DocumentNode != null) { // Find all images with rel attribute var imgNodes = doc.DocumentNode.SelectNodes("//img[@rel]"); From d84b8aa6752f0b37d88d06b0177e2294332e5eb6 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 6 May 2015 11:03:44 +0200 Subject: [PATCH 20/51] Fix duplication of the mysql DbProviderFactory when using NuGet --- build/NuSpecs/tools/Web.config.install.xdt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build/NuSpecs/tools/Web.config.install.xdt b/build/NuSpecs/tools/Web.config.install.xdt index 6215d405fd..e6dc46aab7 100644 --- a/build/NuSpecs/tools/Web.config.install.xdt +++ b/build/NuSpecs/tools/Web.config.install.xdt @@ -37,8 +37,10 @@ - - + + + + From 2e6c643dde59b745a95756077bfd686d0d4f9b48 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 6 May 2015 11:08:25 +0200 Subject: [PATCH 21/51] Bump version --- build/UmbracoVersion.txt | 3 +-- src/SolutionInfo.cs | 2 +- src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/build/UmbracoVersion.txt b/build/UmbracoVersion.txt index 1db884344d..ecb394c050 100644 --- a/build/UmbracoVersion.txt +++ b/build/UmbracoVersion.txt @@ -1,3 +1,2 @@ # Usage: on line 2 put the release version, on line 3 put the version comment (example: beta) -7.2.5 -RC \ No newline at end of file +7.2.5 \ No newline at end of file diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 3b07c788b2..9fd1385311 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -12,4 +12,4 @@ using System.Resources; [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyFileVersion("7.2.5")] -[assembly: AssemblyInformationalVersion("7.2.5-RC")] \ No newline at end of file +[assembly: AssemblyInformationalVersion("7.2.5")] \ No newline at end of file diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 199280fb2b..8f9f84d656 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration /// Gets the version comment (like beta or RC). /// /// The version comment. - public static string CurrentComment { get { return "RC"; } } + public static string CurrentComment { get { return ""; } } // Get the version of the umbraco.dll by looking at a class in that dll // Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx From e358390211a6cc14df569b1ffb906171c0959fcc Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 6 May 2015 11:09:26 +0200 Subject: [PATCH 22/51] Bugfix Xml cache - bad, bad Stephan --- src/Umbraco.Web/umbraco.presentation/content.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index df323c8b8e..4e82e4cb63 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -806,7 +806,7 @@ order by umbracoNode.level, umbracoNode.sortOrder"; } // get it from the database, and register - LoadContentFromDatabase(); + safeXml.Xml = LoadContentFromDatabase(); registerXmlChange = true; } From 1cac4ed0752d3416319a9a2748b5c364a5a6a604 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 08:10:45 +1000 Subject: [PATCH 23/51] Fixes MVC 4.0.0.1 problem once and for all. --- src/SQLCE4Umbraco/app.config | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 4 ++-- src/Umbraco.Core/app.config | 2 +- src/Umbraco.Core/packages.config | 2 +- src/Umbraco.Tests/App.config | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 4 ++-- src/Umbraco.Tests/packages.config | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- src/Umbraco.Web.UI/packages.config | 2 +- src/Umbraco.Web.UI/web.Template.Debug.config | 7 ------- src/Umbraco.Web.UI/web.Template.config | 6 +++--- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- src/Umbraco.Web/app.config | 2 +- src/Umbraco.Web/packages.config | 2 +- src/UmbracoExamine/app.config | 2 +- src/umbraco.MacroEngines/app.config | 2 +- src/umbraco.MacroEngines/packages.config | 2 +- src/umbraco.MacroEngines/umbraco.MacroEngines.csproj | 4 ++-- src/umbraco.businesslogic/app.config | 2 +- src/umbraco.businesslogic/packages.config | 2 +- src/umbraco.businesslogic/umbraco.businesslogic.csproj | 4 ++-- src/umbraco.cms/app.config | 2 +- src/umbraco.controls/app.config | 2 +- src/umbraco.datalayer/app.config | 2 +- src/umbraco.editorControls/app.config | 2 +- src/umbraco.providers/app.config | 2 +- 26 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/SQLCE4Umbraco/app.config b/src/SQLCE4Umbraco/app.config index 8f828418f3..53f3b4c80b 100644 --- a/src/SQLCE4Umbraco/app.config +++ b/src/SQLCE4Umbraco/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index bc272d351e..8abdd10f9f 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -99,9 +99,9 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Core/app.config b/src/Umbraco.Core/app.config index 8f828418f3..53f3b4c80b 100644 --- a/src/Umbraco.Core/app.config +++ b/src/Umbraco.Core/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index d717c88286..1d5de7749b 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 3d35ae5c93..45a43631f7 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -100,7 +100,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 18b9b8d006..2ae4b72a8c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -132,9 +132,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config index 58d314c3b1..4e89abb9a1 100644 --- a/src/Umbraco.Tests/packages.config +++ b/src/Umbraco.Tests/packages.config @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 5de747c1fb..28f8183a7e 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -230,9 +230,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll True - + + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 4a754f6758..3c1927aac8 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -9,7 +9,7 @@ - + diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index 732e2e76ce..d5901a5c5e 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -134,13 +134,6 @@ - - - - - - diff --git a/src/Umbraco.Web.UI/web.Template.config b/src/Umbraco.Web.UI/web.Template.config index 0d8400471f..78007a8114 100644 --- a/src/Umbraco.Web.UI/web.Template.config +++ b/src/Umbraco.Web.UI/web.Template.config @@ -257,10 +257,10 @@ - + - - + + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 08cf22ecd6..5c3c521b16 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -195,9 +195,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Web/app.config b/src/Umbraco.Web/app.config index 957569042f..105ebc53f3 100644 --- a/src/Umbraco.Web/app.config +++ b/src/Umbraco.Web/app.config @@ -29,7 +29,7 @@ - + diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index 315d780852..3fee35e677 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -6,7 +6,7 @@ - + diff --git a/src/UmbracoExamine/app.config b/src/UmbracoExamine/app.config index b77bae14a4..3a3e923d5b 100644 --- a/src/UmbracoExamine/app.config +++ b/src/UmbracoExamine/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.MacroEngines/app.config b/src/umbraco.MacroEngines/app.config index 900c3903d5..d9a8025f65 100644 --- a/src/umbraco.MacroEngines/app.config +++ b/src/umbraco.MacroEngines/app.config @@ -16,7 +16,7 @@ - + diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config index 9951ba7e01..24fd666515 100644 --- a/src/umbraco.MacroEngines/packages.config +++ b/src/umbraco.MacroEngines/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj index a34198b5ce..59e5e4b4c6 100644 --- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj +++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj @@ -89,9 +89,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/umbraco.businesslogic/app.config b/src/umbraco.businesslogic/app.config index b77bae14a4..3a3e923d5b 100644 --- a/src/umbraco.businesslogic/app.config +++ b/src/umbraco.businesslogic/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.businesslogic/packages.config b/src/umbraco.businesslogic/packages.config index 59350953ba..63fd1fb7c3 100644 --- a/src/umbraco.businesslogic/packages.config +++ b/src/umbraco.businesslogic/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/umbraco.businesslogic/umbraco.businesslogic.csproj b/src/umbraco.businesslogic/umbraco.businesslogic.csproj index d74e2dc92e..8f1a26c8fb 100644 --- a/src/umbraco.businesslogic/umbraco.businesslogic.csproj +++ b/src/umbraco.businesslogic/umbraco.businesslogic.csproj @@ -136,9 +136,9 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/umbraco.cms/app.config b/src/umbraco.cms/app.config index b77bae14a4..3a3e923d5b 100644 --- a/src/umbraco.cms/app.config +++ b/src/umbraco.cms/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.controls/app.config b/src/umbraco.controls/app.config index b77bae14a4..3a3e923d5b 100644 --- a/src/umbraco.controls/app.config +++ b/src/umbraco.controls/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.datalayer/app.config b/src/umbraco.datalayer/app.config index 8f828418f3..53f3b4c80b 100644 --- a/src/umbraco.datalayer/app.config +++ b/src/umbraco.datalayer/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/umbraco.editorControls/app.config b/src/umbraco.editorControls/app.config index 734aeed7b8..baa57f9ff7 100644 --- a/src/umbraco.editorControls/app.config +++ b/src/umbraco.editorControls/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.providers/app.config b/src/umbraco.providers/app.config index b77bae14a4..3a3e923d5b 100644 --- a/src/umbraco.providers/app.config +++ b/src/umbraco.providers/app.config @@ -4,7 +4,7 @@ - + From 6e7aa1907393ce6042d64928e1072ceef6fd75ba Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 09:00:43 +1000 Subject: [PATCH 24/51] Fixes U4-5213 in a better way using a query string so it's clear where it redirects to --- src/Umbraco.Web.UI.Client/src/init.js | 13 ++++++----- .../src/views/common/login.controller.js | 22 +++++++++++++++---- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index eb1bdfe2e8..d95c711e0e 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -2,7 +2,6 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', 'appState', 'editorState', 'fileManager', 'assetsService', 'eventsService', '$cookies', '$templateCache', function (userService, $log, $rootScope, $location, navigationService, appState, editorState, fileManager, assetsService, eventsService, $cookies, $templateCache) { - //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 @@ -16,8 +15,10 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', eventsService.on("app.authenticated", function(evt, data) { assetsService._loadInitAssets().then(function() { appState.setGlobalState("isReady", true); - //send the ready event + + //send the ready event with the included returnToPath,returnToSearch data eventsService.emit("app.ready", data); + returnToPath = null, returnToSearch = null; }); }); @@ -44,9 +45,11 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', wiring up it's controller, etc... and then redirect to the rejected URL. */ $rootScope.$on('$routeChangeError', function(event, current, previous, rejection) { event.preventDefault(); - $rootScope.returnToPath = $location.$$path; - $rootScope.returnToSearch = $location.$$search; - $location.path(rejection.path).search(rejection.search); + + //Set the current path before redirecting so we know where to redirect back to + var returnPath = encodeURIComponent($location.url()); + + $location.path(rejection.path).search("returnPath", returnPath); }); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js index 59d8f6bf57..4f78632be5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js @@ -3,8 +3,22 @@ angular.module('umbraco').controller("Umbraco.LoginController", function (events userService._showLoginDialog(); - eventsService.on("app.ready", function(){ - $scope.avatar = "assets/img/application/logo.png"; - $location.path($rootScope.returnToPath || "/").search($rootScope.returnToSearch || ""); + var evtOn = eventsService.on("app.ready", function(evt, data){ + $scope.avatar = "assets/img/application/logo.png"; + + var path = "/"; + + //check if there's a returnPath query string, if so redirect to it + var locationObj = $location.search(); + if (locationObj.returnPath) { + path = decodeURIComponent(locationObj.returnPath); + } + + $location.url(path); }); -}); \ No newline at end of file + + $scope.$on('$destroy', function () { + eventsService.unsubscribe(evtOn); + }); + +}); From 3ce5ff882e1b8a20149e3318a9a16ec8256be325 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 09:11:25 +1000 Subject: [PATCH 25/51] Fixes U4-5213 in a better way using a query string so it's clear where it redirects to --- src/Umbraco.Web.UI.Client/src/init.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/init.js b/src/Umbraco.Web.UI.Client/src/init.js index d95c711e0e..cb79c8e402 100644 --- a/src/Umbraco.Web.UI.Client/src/init.js +++ b/src/Umbraco.Web.UI.Client/src/init.js @@ -46,10 +46,17 @@ app.run(['userService', '$log', '$rootScope', '$location', 'navigationService', $rootScope.$on('$routeChangeError', function(event, current, previous, rejection) { event.preventDefault(); - //Set the current path before redirecting so we know where to redirect back to - var returnPath = encodeURIComponent($location.url()); + var returnPath = null; + if (rejection.path == "/login" || rejection.path.startsWith("/login/")) { + //Set the current path before redirecting so we know where to redirect back to + returnPath = encodeURIComponent($location.url()); + } - $location.path(rejection.path).search("returnPath", returnPath); + $location.path(rejection.path) + if (returnPath) { + $location.search("returnPath", returnPath); + } + }); From 7c01670caf93d5c7f6da16a6dbda43ab4a2895e8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 09:11:39 +1000 Subject: [PATCH 26/51] fixes mem leaks by not unsubscribing from events --- .../directives/umbsections.directive.js | 45 +++++++++++-------- .../src/controllers/main.controller.js | 17 +++++-- .../src/controllers/navigation.controller.js | 40 ++++++++++------- .../views/common/dialogs/user.controller.js | 12 ++--- 4 files changed, 71 insertions(+), 43 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js index 0b91cff44e..2c7303967e 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/umbsections.directive.js @@ -49,26 +49,35 @@ function sectionsDirective($timeout, $window, navigationService, treeService, se } }); } - - //Listen for global state changes - eventsService.on("appState.globalState.changed", function (e, args) { - if (args.key === "showTray") { - scope.showTray = args.value; - } - if (args.key === "stickyNavigation") { - scope.stickyNavigation = args.value; - } - }); - eventsService.on("appState.sectionState.changed", function (e, args) { - if (args.key === "currentSection") { - scope.currentSection = args.value; - } - }); - - eventsService.on("app.reInitialize", function (e, args) { + var evts = []; + + //Listen for global state changes + evts.push(eventsService.on("appState.globalState.changed", function(e, args) { + if (args.key === "showTray") { + scope.showTray = args.value; + } + if (args.key === "stickyNavigation") { + scope.stickyNavigation = args.value; + } + })); + + evts.push(eventsService.on("appState.sectionState.changed", function(e, args) { + if (args.key === "currentSection") { + scope.currentSection = args.value; + } + })); + + evts.push(eventsService.on("app.reInitialize", function(e, args) { //re-load the sections if we're re-initializing (i.e. package installed) - loadSections(); + loadSections(); + })); + + //ensure to unregister from all events! + scope.$on('$destroy', function () { + for (var e in evts) { + eventsService.unsubscribe(evts[e]); + } }); //on page resize 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 cc5dc314d1..6acdaba4ba 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/main.controller.js @@ -48,14 +48,16 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ eventsService.emit("app.closeDialogs", event); }; + var evts = []; + //when a user logs out or timesout - eventsService.on("app.notAuthenticated", function() { + evts.push(eventsService.on("app.notAuthenticated", function() { $scope.authenticated = null; $scope.user = null; - }); + })); //when the app is read/user is logged in, setup the data - eventsService.on("app.ready", function (evt, data) { + evts.push(eventsService.on("app.ready", function (evt, data) { $scope.authenticated = data.authenticated; $scope.user = data.user; @@ -73,7 +75,7 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ notificationsService.add(notification); } } - }); + }) //if the user has changed we need to redirect to the root so they don't try to continue editing the //last item in the URL (NOTE: the user id can equal zero, so we cannot just do !data.lastUserId since that will resolve to true) @@ -104,6 +106,13 @@ function MainController($scope, $rootScope, $location, $routeParams, $timeout, $ }, 3000); } + })); + + //ensure to unregister from all events! + $scope.$on('$destroy', function () { + for (var e in evts) { + eventsService.unsubscribe(evts[e]); + } }); } 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 80efaa8272..0c6bcf941a 100644 --- a/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js +++ b/src/Umbraco.Web.UI.Client/src/controllers/navigation.controller.js @@ -47,15 +47,17 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, $scope.selectedId = navigationService.currentId; + var evts = []; + //Listen for global state changes - eventsService.on("appState.globalState.changed", function (e, args) { + evts.push(eventsService.on("appState.globalState.changed", function(e, args) { if (args.key === "showNavigation") { $scope.showNavigation = args.value; } - }); + })); //Listen for menu state changes - eventsService.on("appState.menuState.changed", function (e, args) { + evts.push(eventsService.on("appState.menuState.changed", function(e, args) { if (args.key === "showMenuDialog") { $scope.showContextMenuDialog = args.value; } @@ -71,20 +73,21 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, if (args.key === "currentNode") { $scope.menuNode = args.value; } - }); + })); //Listen for section state changes - eventsService.on("appState.treeState.changed", function (e, args) { + evts.push(eventsService.on("appState.treeState.changed", function(e, args) { var f = args; if (args.value.root && args.value.root.metaData.containsTrees === false) { $rootScope.emptySection = true; - }else{ + } + else { $rootScope.emptySection = false; } - }); + })); //Listen for section state changes - eventsService.on("appState.sectionState.changed", function (e, args) { + evts.push(eventsService.on("appState.sectionState.changed", function(e, args) { //section changed if (args.key === "currentSection") { $scope.currentSection = args.value; @@ -93,26 +96,26 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, if (args.key === "showSearchResults") { $scope.showSearchResults = args.value; } - }); + })); //This reacts to clicks passed to the body element which emits a global call to close all dialogs - eventsService.on("app.closeDialogs", function (event) { + evts.push(eventsService.on("app.closeDialogs", function(event) { if (appState.getGlobalState("stickyNavigation")) { navigationService.hideNavigation(); //TODO: don't know why we need this? - we are inside of an angular event listener. angularHelper.safeApply($scope); } - }); + })); //when a user logs out or timesout - eventsService.on("app.notAuthenticated", function () { + evts.push(eventsService.on("app.notAuthenticated", function() { $scope.authenticated = false; - }); + })); //when the application is ready and the user is authorized setup the data - eventsService.on("app.ready", function (evt, data) { + evts.push(eventsService.on("app.ready", function(evt, data) { $scope.authenticated = true; - }); + })); //this reacts to the options item in the tree //todo, migrate to nav service @@ -151,6 +154,13 @@ function NavigationController($scope, $rootScope, $location, $log, $routeParams, }, 300); } }; + + //ensure to unregister from all events! + $scope.$on('$destroy', function () { + for (var e in evts) { + eventsService.unsubscribe(evts[e]); + } + }); } //register it diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js index 5979962128..bd813d7baa 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js @@ -5,14 +5,14 @@ angular.module("umbraco") $scope.history = historyService.getCurrent(); $scope.version = Umbraco.Sys.ServerVariables.application.version + " assembly: " + Umbraco.Sys.ServerVariables.application.assemblyVersion; - var evtHandlers = []; - evtHandlers.push(eventsService.on("historyService.add", function (e, args) { + var evts = []; + evts.push(eventsService.on("historyService.add", function (e, args) { $scope.history = args.all; })); - evtHandlers.push(eventsService.on("historyService.remove", function (e, args) { + evts.push(eventsService.on("historyService.remove", function (e, args) { $scope.history = args.all; })); - evtHandlers.push(eventsService.on("historyService.removeAll", function (e, args) { + evts.push(eventsService.on("historyService.removeAll", function (e, args) { $scope.history = []; })); @@ -62,8 +62,8 @@ angular.module("umbraco") //remove all event handlers $scope.$on('$destroy', function () { - for (var i = 0; i < evtHandlers.length; i++) { - evtHandlers[i](); + for (var e = 0; e < evts.length; e++) { + evts[e](); } }); From f4bdcae411ab8cadaf534bc55f66056e8bf29079 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 10:47:36 +1000 Subject: [PATCH 27/51] Fixes: U4-6236 umbraco 7 macro parameters saving "null" --- .../src/views/common/dialogs/insertmacro.controller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js index c132d3af2e..dbb86e87ec 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/insertmacro.controller.js @@ -73,7 +73,7 @@ function InsertMacroController($scope, entityResource, macroResource, umbPropEdi var val = item.value; - if (!_.isString(item.value)) { + if (item.value != null && item.value != undefined && !_.isString(item.value)) { try { val = angular.toJson(val); } From 813f1a1f2dd83464ab557c9be8023ff13f255fe6 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 11:43:53 +1000 Subject: [PATCH 28/51] Fixes: U4-6035 Properrty.WasDirty() always returns false --- src/Umbraco.Core/Models/Content.cs | 69 +-------------- src/Umbraco.Core/Models/ContentBase.cs | 87 ++++++++++++++++++- src/Umbraco.Core/Models/ContentExtensions.cs | 32 +++++-- .../EntityBase/TracksChangesEntityBase.cs | 2 +- src/Umbraco.Tests/Models/ContentTests.cs | 12 +++ 5 files changed, 124 insertions(+), 78 deletions(-) diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index f4af3b842e..a805e01b93 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -337,74 +337,7 @@ namespace Umbraco.Core.Models ChangePublishedState(PublishedState.Unpublished); } } - - /// - /// Indicates whether a specific property on the current entity is dirty. - /// - /// Name of the property to check - /// True if Property is dirty, otherwise False - public override bool IsPropertyDirty(string propertyName) - { - bool existsInEntity = base.IsPropertyDirty(propertyName); - if (existsInEntity) - return true; - - return Properties.Any(x => x.IsPropertyDirty(propertyName)); - } - - /// - /// Indicates whether the current entity is dirty. - /// - /// True if entity is dirty, otherwise False - public override bool IsDirty() - { - return IsEntityDirty() || IsAnyUserPropertyDirty(); - } - - /// - /// Returns true if only the entity properties are direty - /// - /// - public bool IsEntityDirty() - { - return base.IsDirty(); - } - - /// - /// Returns true if any of the properties are dirty - /// - /// - public bool IsAnyUserPropertyDirty() - { - return Properties.Any(x => x.IsDirty()); - } - - /// - /// Returns a list of all dirty user defined properties - /// - /// - public IEnumerable GetDirtyUserProperties() - { - return Properties.Where(x => x.IsDirty()).Select(x => x.Alias); - } - - /// - /// Resets dirty properties by clearing the dictionary used to track changes. - /// - /// - /// Please note that resetting the dirty properties could potentially - /// obstruct the saving of a new or updated entity. - /// - public override void ResetDirtyProperties() - { - base.ResetDirtyProperties(); - - foreach (var property in Properties) - { - property.ResetDirtyProperties(); - } - } - + /// /// Method to call when Entity is being saved /// diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index da9061fdc6..6beead06e6 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -466,6 +466,8 @@ namespace Umbraco.Core.Models public abstract void ChangeTrashedState(bool isTrashed, int parentId = -20); + #region Dirty property handling + /// /// We will override this method to ensure that when we reset the dirty properties that we /// also reset the dirty changes made to the content's Properties (user defined) @@ -480,6 +482,89 @@ namespace Umbraco.Core.Models prop.ResetDirtyProperties(rememberPreviouslyChangedProperties); } } - + + /// + /// Indicates whether the current entity is dirty. + /// + /// True if entity is dirty, otherwise False + public override bool IsDirty() + { + return IsEntityDirty() || this.IsAnyUserPropertyDirty(); + } + + /// + /// Indicates whether the current entity was dirty. + /// + /// True if entity was dirty, otherwise False + public override bool WasDirty() + { + return WasEntityDirty() || this.WasAnyUserPropertyDirty(); + } + + /// + /// Returns true if only the entity properties are dirty + /// + /// + public bool IsEntityDirty() + { + return base.IsDirty(); + } + + /// + /// Returns true if only the entity properties were dirty + /// + /// + public bool WasEntityDirty() + { + return base.WasDirty(); + } + + /// + /// Indicates whether a specific property on the current entity is dirty. + /// + /// Name of the property to check + /// + /// True if any of the class properties are dirty or + /// True if any of the user defined PropertyType properties are dirty based on their alias, + /// otherwise False + /// + public override bool IsPropertyDirty(string propertyName) + { + bool existsInEntity = base.IsPropertyDirty(propertyName); + if (existsInEntity) + return true; + + if (Properties.Contains(propertyName)) + { + return Properties[propertyName].IsDirty(); + } + + return false; + } + + /// + /// Indicates whether a specific property on the current entity was changed and the changes were committed + /// + /// Name of the property to check + /// + /// True if any of the class properties are dirty or + /// True if any of the user defined PropertyType properties are dirty based on their alias, + /// otherwise False + /// + public override bool WasPropertyDirty(string propertyName) + { + bool existsInEntity = base.WasPropertyDirty(propertyName); + if (existsInEntity) + return true; + + if (Properties.Contains(propertyName)) + { + return Properties[propertyName].WasDirty(); + } + + return false; + } + + #endregion } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/ContentExtensions.cs b/src/Umbraco.Core/Models/ContentExtensions.cs index 3c6a892900..62c32546b3 100644 --- a/src/Umbraco.Core/Models/ContentExtensions.cs +++ b/src/Umbraco.Core/Models/ContentExtensions.cs @@ -77,10 +77,9 @@ namespace Umbraco.Core.Models /// internal static bool RequiresSaving(this IContent entity, PublishedState publishedState) { - var dirtyEntity = (ICanBeDirty)entity; - var publishedChanged = dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished; + var publishedChanged = entity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished; //check if any user prop has changed - var propertyValueChanged = ((Content)entity).IsAnyUserPropertyDirty(); + var propertyValueChanged = entity.IsAnyUserPropertyDirty(); //We need to know if any other property apart from Published was changed here //don't create a new version if the published state has changed to 'Save' but no data has actually been changed @@ -114,6 +113,25 @@ namespace Umbraco.Core.Models return ShouldCreateNewVersion(entity, publishedState); } + /// + /// Returns a list of all dirty user defined properties + /// + /// + public static IEnumerable GetDirtyUserProperties(this IContentBase entity) + { + return entity.Properties.Where(x => x.IsDirty()).Select(x => x.Alias); + } + + public static bool IsAnyUserPropertyDirty(this IContentBase entity) + { + return entity.Properties.Any(x => x.IsDirty()); + } + + public static bool WasAnyUserPropertyDirty(this IContentBase entity) + { + return entity.Properties.Any(x => x.WasDirty()); + } + /// /// Determines if a new version should be created /// @@ -128,15 +146,13 @@ namespace Umbraco.Core.Models /// internal static bool ShouldCreateNewVersion(this IContent entity, PublishedState publishedState) { - var dirtyEntity = (ICanBeDirty)entity; - //check if the published state has changed or the language - var publishedChanged = dirtyEntity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished; - var langChanged = dirtyEntity.IsPropertyDirty("Language"); + var publishedChanged = entity.IsPropertyDirty("Published") && publishedState != PublishedState.Unpublished; + var langChanged = entity.IsPropertyDirty("Language"); var contentChanged = publishedChanged || langChanged; //check if any user prop has changed - var propertyValueChanged = ((Content)entity).IsAnyUserPropertyDirty(); + var propertyValueChanged = entity.IsAnyUserPropertyDirty(); //return true if published or language has changed if (contentChanged) diff --git a/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs b/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs index cd5b762f84..0d5378d253 100644 --- a/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs +++ b/src/Umbraco.Core/Models/EntityBase/TracksChangesEntityBase.cs @@ -78,7 +78,7 @@ namespace Umbraco.Core.Models.EntityBase /// Indicates that the entity had been changed and the changes were committed /// /// - public bool WasDirty() + public virtual bool WasDirty() { return _lastPropertyChangedInfo != null && _lastPropertyChangedInfo.Any(); } diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index de4f95863e..72d1e31fec 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -712,9 +712,21 @@ namespace Umbraco.Tests.Models // Act content.SetPropertyValue("title", "new title"); + Assert.That(content.IsEntityDirty(), Is.False); + Assert.That(content.IsDirty(), Is.True); + Assert.That(content.IsPropertyDirty("title"), Is.True); + Assert.That(content.IsAnyUserPropertyDirty(), Is.True); + Assert.That(content.GetDirtyUserProperties().Count(), Is.EqualTo(1)); + Assert.That(content.Properties[0].IsDirty(), Is.True); + Assert.That(content.Properties["title"].IsDirty(), Is.True); + content.ResetDirtyProperties(); //this would be like committing the entity // Assert + Assert.That(content.WasDirty(), Is.True); + Assert.That(content.Properties[0].WasDirty(), Is.True); + + Assert.That(content.WasPropertyDirty("title"), Is.True); Assert.That(content.Properties["title"].IsDirty(), Is.False); Assert.That(content.Properties["title"].WasDirty(), Is.True); From 6a0656fbb087f57bc2708e44d0460735a09caf2b Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 11:59:10 +1000 Subject: [PATCH 29/51] fixes spacing for radio/check boxes (U4-6036) tested in ie, ff and chrome --- src/Umbraco.Web.UI.Client/src/less/forms.less | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Umbraco.Web.UI.Client/src/less/forms.less b/src/Umbraco.Web.UI.Client/src/less/forms.less index 66da7a1f61..1091a95ea8 100644 --- a/src/Umbraco.Web.UI.Client/src/less/forms.less +++ b/src/Umbraco.Web.UI.Client/src/less/forms.less @@ -306,6 +306,7 @@ textarea { .checkbox input[type="checkbox"] { float: left; margin-left: 0px; + margin-right:5px; } // Move the options list down to align with labels From 4e6a3458d0def5003a2c51309cf04a8c8b7a5f6e Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 12:57:23 +1000 Subject: [PATCH 30/51] Fixes: U4-6600 Label on files not just folders in file browser (media) and fixes up the last image rendered in the photo browser, as well as the overlays, whitespace and overflow and vertical alignment. --- .../src/common/services/util.service.js | 9 ++++---- .../src/less/property-editors.less | 23 ++++++++++--------- .../directives/html/umb-photo-folder.html | 9 ++++---- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js index b726bef44a..dff563462d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js @@ -206,7 +206,7 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, me }, /** builds an image grid row */ - buildRow: function(imgs, maxRowHeight, minDisplayHeight, maxRowWidth, idealImgPerRow, margin) { + buildRow: function(imgs, maxRowHeight, minDisplayHeight, maxRowWidth, idealImgPerRow, margin, totalRemaining) { var currRowWidth = 0; var row = { images: [] }; @@ -253,8 +253,8 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, me this.setImageStyle(row.images[j], sizes[j].width, sizes[j].height, margin, bottomMargin); } - if (row.images.length === 1) { - //if there's only one image on the row, set the container to max width + if (row.images.length === 1 && totalRemaining > 1) { + //if there's only one image on the row and there are more images remaining, set the container to max width row.images[0].style.width = maxRowWidth + "px"; } @@ -298,7 +298,8 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, me var currImgs = images.slice(imagesProcessed); //build the row - var row = this.buildRow(currImgs, maxRowHeight, minDisplayHeight, maxRowWidth, idealImgPerRow, margin); + var remaining = images.length - imagesProcessed; + var row = this.buildRow(currImgs, maxRowHeight, minDisplayHeight, maxRowWidth, idealImgPerRow, margin, remaining); if (row.images.length > 0) { rows.push(row); imagesProcessed += row.images.length; diff --git a/src/Umbraco.Web.UI.Client/src/less/property-editors.less b/src/Umbraco.Web.UI.Client/src/less/property-editors.less index 21ee03e0ff..7c7c8414ee 100644 --- a/src/Umbraco.Web.UI.Client/src/less/property-editors.less +++ b/src/Umbraco.Web.UI.Client/src/less/property-editors.less @@ -309,7 +309,7 @@ ul.color-picker li a { } .umb-folderbrowser .selector-overlay{ - display: none !important; + display: none; } .umb-upload-drop-zone{ @@ -379,16 +379,10 @@ ul.color-picker li a { background-color: @grayLighter; } -.umb-photo-folder .picrow div.umb-photo .umb-photo-img-name{ - overflow: hidden; - text-overlow: ellipsis; - white-space: no-wrap; -} - .umb-photo-folder a:hover{text-decoration: none} .umb-photo-folder .umb-non-thumbnail{ text-align: center; - vertical-align: center; + vertical-align: middle; font-size: 12px; background: @grayLighter; color: @black; @@ -396,8 +390,7 @@ ul.color-picker li a { } //this is a temp hack, to provide selectors in the dialog: -.umb-photo-folder .pic:hover .selector-overlay, -.umb-photo-folder .picrow div.umb-photo .umb-photo-img-name{ +.umb-photo-folder .pic:hover .selector-overlay { position: absolute; bottom: 0px; left: 0px; @@ -409,6 +402,11 @@ ul.color-picker li a { text-align: center; color: white; opacity: 0.4; + text-decoration:none; + + overflow: hidden; + text-overlow: ellipsis; + white-space: nowrap; } .umb-photo-folder .umb-non-thumbnail i{ @@ -417,7 +415,10 @@ ul.color-picker li a { line-height: 60px; display: block; margin: auto; - padding-top: 20px; + /*vertically aligns */ + position: relative; + top: 50%; + transform: translateY(-50%); } .umb-photo-folder .selected{ diff --git a/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html b/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html index 00382a0a3e..6353c49152 100644 --- a/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html +++ b/src/Umbraco.Web.UI.Client/src/views/directives/html/umb-photo-folder.html @@ -12,16 +12,17 @@
    {{img.name}} +
    - {{img.name}} +
    - - Select + + Select + {{img.name}} From a69c7dd1fc52de6b5eaa7a1e658e1ed8c4f5a288 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 13:09:29 +1000 Subject: [PATCH 31/51] Manually merges PR: 564 --- src/umbraco.controls/PropertyPanel.cs | 38 +++++++++++++++------------ 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/umbraco.controls/PropertyPanel.cs b/src/umbraco.controls/PropertyPanel.cs index a06a9818e7..484f69fa93 100644 --- a/src/umbraco.controls/PropertyPanel.cs +++ b/src/umbraco.controls/PropertyPanel.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text; using System.Web.UI; @@ -7,34 +8,24 @@ namespace umbraco.uicontrols { public class PropertyPanel : System.Web.UI.WebControls.Panel { - public PropertyPanel() - { - - } - + private Control _control; private string _text = string.Empty; + public string Text { get { return _text; } set { _text = value; } } - protected override void OnLoad(System.EventArgs EventArguments) + protected override void OnLoad(EventArgs eventArguments) { } - protected override void Render(System.Web.UI.HtmlTextWriter writer) + protected override void Render(HtmlTextWriter writer) { - this.ViewStateMode = ViewStateMode.Disabled; - this.CreateChildControls(); - string styleString = ""; + ViewStateMode = ViewStateMode.Disabled; + CreateChildControls(); - foreach (string key in this.Style.Keys) - { - styleString += key + ":" + this.Style[key] + ";"; - } - - var inGroup = this.Parent.GetType() == typeof(PropertyGroup); if (string.IsNullOrEmpty(_text)) CssClass += " hidelabel"; @@ -45,7 +36,20 @@ namespace umbraco.uicontrols if (_text != string.Empty) { - writer.WriteLine(""); + if (_control == null) + { + _control = Controls.OfType().FirstOrDefault(c => c.Visible && (c.GetType().Name.Contains("Literal") == false)); + } + + if (_control == null) + { + writer.WriteLine("{0}", _text); + } + else + { + writer.WriteLine("", _control != null ? _control.ClientID : "", _text); + } + } writer.WriteLine("
    "); From fec9d066f09c57dc81a9dae6859740622774f948 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 13:24:59 +1000 Subject: [PATCH 32/51] Merge branch 'property-editor-fixes' of https://github.com/pynej/Umbraco-CMS into pynej-property-editor-fixes Conflicts: src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs --- .../contentpicker/contentpicker.controller.js | 2 +- .../propertyeditors/integer/integer.html | 4 +- .../markdowneditor.controller.js | 6 ++- .../multipletextbox/multipletextbox.html | 4 +- .../ContentPickerPropertyEditor.cs | 6 ++- .../PropertyEditors/IntegerPropertyEditor.cs | 38 ++++++++++++++++++- 6 files changed, 52 insertions(+), 8 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js index 8c656b2d4b..8847db455b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js @@ -53,7 +53,7 @@ function contentPickerController($scope, dialogService, entityResource, editorSt startNode: { query: "", type: "content", - id: -1 + id: $scope.model.config.startNodeId ? $scope.model.config.startNodeId : -1 // get start node for simple Content Picker } }; diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/integer/integer.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/integer/integer.html index 13cd4505d7..251a6066d8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/integer/integer.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/integer/integer.html @@ -1,8 +1,8 @@ 
    - + fix-number min="{{model.config.min}}" max="{{model.config.max}}" step="{{model.config.step}}" /> Not a number {{propertyForm.requiredField.errorMsg}} diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js index a5ee788a16..9d17d61444 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js @@ -18,7 +18,9 @@ function ($scope, assetsService, dialogService, $timeout) { ]) .then(function () { - //this function will execute when all dependencies have loaded + // we need a short delay to wait for the textbox to appear. + setTimeout(function() { + //this function will execute when all dependencies have loaded // but in the case that they've been previously loaded, we can only // init the md editor after this digest because the DOM needs to be ready first // so run the init on a timeout @@ -38,7 +40,7 @@ function ($scope, assetsService, dialogService, $timeout) { return true; // tell the editor that we'll take care of getting the image url }); - }); + }, 200); }); //load the seperat css for the editor to avoid it blocking our js loading TEMP HACK diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html index 9eeab2c3b4..4d76305fcd 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html @@ -1,13 +1,15 @@ 
    +
    + -
    +
    diff --git a/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs index 10e63c8900..1789c6dae6 100644 --- a/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/ContentPickerPropertyEditor.cs @@ -12,7 +12,8 @@ namespace Umbraco.Web.PropertyEditors { _internalPreValues = new Dictionary { - {"showEditButton", "0"} + {"showEditButton", "0"}, + {"startNodeId", "-1"} }; } @@ -32,6 +33,9 @@ namespace Umbraco.Web.PropertyEditors { [PreValueField("showEditButton", "Show edit button (this feature is in preview!)", "boolean")] public string ShowEditButton { get; set; } + + [PreValueField("startNodeId", "Start node", "treepicker")] + public int StartNodeId { get; set; } } } diff --git a/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs index 81d91ef10a..b587c2620e 100644 --- a/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/IntegerPropertyEditor.cs @@ -16,6 +16,42 @@ namespace Umbraco.Web.PropertyEditors editor.Validators.Add(new IntegerValidator()); return editor; } - + + protected override PreValueEditor CreatePreValueEditor() + { + return new IntegerPreValueEditor(); + } + + /// + /// A custom pre-value editor class to deal with the legacy way that the pre-value data is stored. + /// + internal class IntegerPreValueEditor : PreValueEditor + { + public IntegerPreValueEditor() + { + //create the fields + Fields.Add(new PreValueField(new IntegerValidator()) + { + Description = "Enter the minimum amount of number to be entered", + Key = "min", + View = "number", + Name = "Minimum" + }); + Fields.Add(new PreValueField(new IntegerValidator()) + { + Description = "Enter the intervals amount between each step of number to be entered", + Key = "step", + View = "number", + Name = "Step Size" + }); + Fields.Add(new PreValueField(new IntegerValidator()) + { + Description = "Enter the maximum amount of number to be entered", + Key = "max", + View = "number", + Name = "Maximum" + }); + } + } } } \ No newline at end of file From 8443513b2b33cb0e3e21ba74f11c81442317db72 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 13:39:28 +1000 Subject: [PATCH 33/51] fixes sorting with multipletextbox --- .../src/common/services/util.service.js | 2 +- .../markdowneditor.controller.js | 61 ++++++++++--------- .../multipletextbox.controller.js | 8 +++ .../multipletextbox/multipletextbox.html | 29 ++++----- src/umbraco.controls/PropertyPanel.cs | 2 +- 5 files changed, 56 insertions(+), 46 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js index dff563462d..d83a0f3eaa 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js @@ -278,7 +278,7 @@ function umbPhotoFolderHelper($compile, $log, $timeout, $filter, imageHelper, me buildGrid: function(images, maxRowWidth, maxRowHeight, startingIndex, minDisplayHeight, idealImgPerRow, margin,imagesOnly) { var rows = []; - var imagesProcessed = 0; + var imagesProcessed = 0; //first fill in all of the original image sizes and URLs for (var i = startingIndex; i < images.length; i++) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js index 9d17d61444..8893ebd523 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/markdowneditor/markdowneditor.controller.js @@ -1,7 +1,5 @@ -angular.module("umbraco") -.controller("Umbraco.PropertyEditors.MarkdownEditorController", //inject umbracos assetsServce and dialog service -function ($scope, assetsService, dialogService, $timeout) { +function MarkdownEditorController($scope, assetsService, dialogService, $timeout) { //tell the assets service to load the markdown.editor libs from the markdown editors //plugin folder @@ -11,38 +9,41 @@ function ($scope, assetsService, dialogService, $timeout) { } assetsService - .load([ - "lib/markdown/markdown.converter.js", + .load([ + "lib/markdown/markdown.converter.js", "lib/markdown/markdown.sanitizer.js", "lib/markdown/markdown.editor.js" ]) - .then(function () { - - // we need a short delay to wait for the textbox to appear. - setTimeout(function() { - //this function will execute when all dependencies have loaded - // but in the case that they've been previously loaded, we can only - // init the md editor after this digest because the DOM needs to be ready first - // so run the init on a timeout - $timeout(function() { - var converter2 = new Markdown.Converter(); - var editor2 = new Markdown.Editor(converter2, "-" + $scope.model.alias); - editor2.run(); + .then(function () { - //subscribe to the image dialog clicks - editor2.hooks.set("insertImageDialog", function (callback) { + // we need a short delay to wait for the textbox to appear. + setTimeout(function () { + //this function will execute when all dependencies have loaded + // but in the case that they've been previously loaded, we can only + // init the md editor after this digest because the DOM needs to be ready first + // so run the init on a timeout + $timeout(function () { + var converter2 = new Markdown.Converter(); + var editor2 = new Markdown.Editor(converter2, "-" + $scope.model.alias); + editor2.run(); - dialogService.mediaPicker({ - callback: function (data) { - callback(data.image); - } + //subscribe to the image dialog clicks + editor2.hooks.set("insertImageDialog", function (callback) { + + dialogService.mediaPicker({ + callback: function (data) { + callback(data.image); + } + }); + + return true; // tell the editor that we'll take care of getting the image url }); + }, 200); + }); - return true; // tell the editor that we'll take care of getting the image url - }); - }, 200); - }); + //load the seperat css for the editor to avoid it blocking our js loading TEMP HACK + assetsService.loadCss("lib/markdown/markdown.css"); + }) +} - //load the seperat css for the editor to avoid it blocking our js loading TEMP HACK - assetsService.loadCss("lib/markdown/markdown.css"); -}); \ No newline at end of file +angular.module("umbraco").controller("Umbraco.PropertyEditors.MarkdownEditorController", MarkdownEditorController); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js index 1b0e863097..771d854aae 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.controller.js @@ -1,5 +1,13 @@ function MultipleTextBoxController($scope) { + $scope.sortableOptions = { + axis: 'y', + containment: 'parent', + cursor: 'move', + items: '> div.control-group', + tolerance: 'pointer' + }; + if (!$scope.model.value) { $scope.model.value = []; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html index 4d76305fcd..447af77bc4 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/multipletextbox/multipletextbox.html @@ -1,19 +1,20 @@  + +
    \ No newline at end of file diff --git a/src/umbraco.controls/PropertyPanel.cs b/src/umbraco.controls/PropertyPanel.cs index 484f69fa93..786081e6ae 100644 --- a/src/umbraco.controls/PropertyPanel.cs +++ b/src/umbraco.controls/PropertyPanel.cs @@ -16,7 +16,7 @@ namespace umbraco.uicontrols get { return _text; } set { _text = value; } } - + protected override void OnLoad(EventArgs eventArguments) { } From d0dc5406cc88ab80bf490672e44dd83c3eeae81b Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 7 May 2015 16:39:00 +1000 Subject: [PATCH 34/51] fixes package merging --- src/Umbraco.Core/packages.config | 31 +++++++++--------- src/Umbraco.Web.UI/packages.config | 50 +++++++++++++++--------------- 2 files changed, 40 insertions(+), 41 deletions(-) diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index d87ded7cac..9e91a9bd71 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -1,27 +1,26 @@  - - - + + + - - - - - - - - + + + + + + - - - - - + + + + + + \ No newline at end of file diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index eeb149d327..9f2dc64937 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -1,34 +1,34 @@  - - - - + + + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + - + From 3b849987bf6d3d1cefd959cb32c4fd7c4170141b Mon Sep 17 00:00:00 2001 From: Heather Floyd Date: Thu, 7 May 2015 16:41:12 -0400 Subject: [PATCH 35/51] Small fixes to 'en' language file. Update of 'en-us' language file to match 'en' language file. --- src/Umbraco.Web.UI/umbraco/config/lang/en.xml | 10 ++-- .../umbraco/config/lang/en_us.xml | 48 +++++++++---------- 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml index c5c6148b2f..b66a70bdfb 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en.xml @@ -244,8 +244,8 @@ Name the %0%... Enter a name... Type to search... - Type to filter... - Type to add tags (press enter after each tag)... + Type to filter... + Type to add tags (press enter after each tag)... Allow at root @@ -679,9 +679,11 @@ To manage your website, simply open the Umbraco back office and start adding con If you just want to setup simple protection using a single login and password - + + ]]> + diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index 41d7f43a24..856bcaca4f 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -44,16 +44,16 @@ Invalid node. Invalid domain format. Domain has already been assigned. - Domain Language + Domain New domain '%0%' has been created Domain '%0%' is deleted Domain '%0%' has already been assigned + Domain '%0%' has been updated + Edit Current Domains
    One-level paths in domains are supported, eg. "example.com/en". However, they should be avoided. Better use the culture setting above.]]>
    - Domain '%0%' has been updated - Edit Current Domains Inherit Culture or inherit culture from parent nodes. Will also apply
    @@ -63,8 +63,6 @@ Viewing for - - Select Select current folder @@ -134,7 +132,7 @@ This item has been changed after publication This item is not published Last published - There are no items show in the list. + There are no items to show in the list. Media Type Link to media item(s) Member Group @@ -162,8 +160,7 @@ Remove file(s) Link to document Member of group(s) - Not a member of group(s) - + Not a member of group(s) Child items Target @@ -175,9 +172,7 @@ Where do you want to create the new %0% Create an item under Choose a type and a title - "document types".]]> - "media types".]]> @@ -250,6 +245,7 @@ Enter a name... Type to search... Type to filter... + Type to add tags (press enter after each tag)... @@ -412,7 +408,6 @@ Width Yes Folder - Search results @@ -560,11 +555,9 @@ To manage your website, simply open the Umbraco back office and start adding con Happy thunderous Thursday Happy funky Friday Happy Caturday - - log in below + Log in below Session timed out - © 2001 - %0%
    Umbraco.com

    ]]>
    - + © 2001 - %0%
    Umbraco.com

    ]]>
    Dashboard @@ -715,16 +708,16 @@ To manage your website, simply open the Umbraco back office and start adding con You have not configured any approved colors - Add external link - Add internal link - Add + enter external link + choose internal page Caption - Internal page - URL - Move Down - Move Up + Link Open in new window - Remove link + enter the display caption + Enter the link + + + Reset Current version @@ -751,8 +744,8 @@ To manage your website, simply open the Umbraco back office and start adding con Statistics Translation Users - Help + Forms Analytics @@ -859,6 +852,10 @@ To manage your website, simply open the Umbraco back office and start adding con Add rows to your layout below and add your first element]]> + Click to embed + Click to insert image + Image caption... + Write here... Grid layouts Layouts are the overall work area for the grid editor, usually you only need one or two different layouts Add grid layout @@ -1032,12 +1029,11 @@ To manage your website, simply open the Umbraco back office and start adding con Select pages to modify their permissions Search all children Start Node in Content - Username + Name User permissions User type User types Writer - Your profile Your recent history Session expires in From 11b5123bbba58fba9ef51487e0e11777eaeedc23 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 8 May 2015 19:13:58 +1000 Subject: [PATCH 36/51] fixes datatokens dictionary check and ensures that webapi is initialized at the very end of the boot cycle. --- src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs | 3 ++- src/Umbraco.Web/WebBootManager.cs | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs b/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs index ace4061985..0a6ce9f841 100644 --- a/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs +++ b/src/Umbraco.Web/WebApi/NamespaceHttpControllerSelector.cs @@ -27,7 +27,8 @@ namespace Umbraco.Web.WebApi var routeData = request.GetRouteData(); if (routeData == null || routeData.Route == null - || routeData.Route.DataTokens == null + || routeData.Route.DataTokens == null + || routeData.Route.DataTokens.ContainsKey("Namespaces") == false || routeData.Route.DataTokens["Namespaces"] == null) return base.SelectController(request); diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 972774574e..99bdaada4c 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -192,6 +192,9 @@ namespace Umbraco.Web } } + //Now ensure webapi is initialized after everything + GlobalConfiguration.Configuration.EnsureInitialized(); + return this; } From c34605937c85a8c1c101b7ae04699b19f24926ac Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Sun, 10 May 2015 17:47:32 +0200 Subject: [PATCH 37/51] U4-6603 Log failed login attempts #U4-6603 Fixed --- .../Editors/AuthenticationController.cs | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index 00498f7e61..378306fdb4 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -21,6 +21,7 @@ using Umbraco.Web.Security; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; using umbraco.providers; +using Umbraco.Core.Logging; namespace Umbraco.Web.Editors { @@ -102,23 +103,25 @@ namespace Umbraco.Web.Editors [SetAngularAntiForgeryTokens] public UserDetail PostLogin(LoginModel loginModel) { + var http = this.TryGetHttpContext(); + if (http.Success == false) + throw new InvalidOperationException("This method requires that an HttpContext be active"); + + var ipAddress = GetIPAddress(http.Result); + if (UmbracoContext.Security.ValidateBackOfficeCredentials(loginModel.Username, loginModel.Password)) { var user = Security.GetBackOfficeUser(loginModel.Username); //TODO: Clean up the int cast! var ticket = UmbracoContext.Security.PerformLogin(user); - - var http = this.TryGetHttpContext(); - if (http.Success == false) - { - throw new InvalidOperationException("This method requires that an HttpContext be active"); - } http.Result.AuthenticateCurrentRequest(ticket, false); var result = Mapper.Map(user); //set their remaining seconds result.SecondsUntilTimeout = ticket.GetRemainingAuthSeconds(); + + LogHelper.Info(string.Format("Login attempt succeeded for username {0} from IP address {1}", loginModel.Username, ipAddress)); return result; } @@ -126,6 +129,8 @@ namespace Umbraco.Web.Editors // by our angular helper because it thinks that we need to re-perform the request once we are // authorized and we don't want to return a 403 because angular will show a warning msg indicating // that the user doesn't have access to perform this function, we just want to return a normal invalid msg. + + LogHelper.Info(string.Format("Login attempt failed for username {0} from IP address {1}", loginModel.Username, ipAddress)); throw new HttpResponseException(HttpStatusCode.BadRequest); } @@ -141,5 +146,20 @@ namespace Umbraco.Web.Editors { return Request.CreateResponse(HttpStatusCode.OK); } + + // From: http://stackoverflow.com/a/740431/5018 + protected string GetIPAddress(HttpContextBase httpContext) + { + var ipAddress = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; + + if (string.IsNullOrEmpty(ipAddress)) + return httpContext.Request.ServerVariables["REMOTE_ADDR"]; + + var addresses = ipAddress.Split(','); + if (addresses.Length != 0) + return addresses[0]; + + return httpContext.Request.ServerVariables["REMOTE_ADDR"]; + } } } \ No newline at end of file From 9f82ae1db7cbbfe7d42eddec057ab178e98c879a Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 11 May 2015 10:52:38 +1000 Subject: [PATCH 38/51] unspec to mvc 4.0.0.1 --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index d197d44049..1bb1a78d03 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -15,7 +15,7 @@ en-US umbraco - + From a4a49b14666f843a34f0b5e7c0ae06be821c3b8f Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 11 May 2015 11:45:13 +1000 Subject: [PATCH 39/51] Revert "Fixes MVC 4.0.0.1 problem once and for all." - All MVC ref's are 4.0.0.0, no web config transforms (also there was never a 4.0.0.1 version of System.Net.Http). Everything works on my machine now, even with 4.0.0.1 installed in the GAC. --- src/SQLCE4Umbraco/app.config | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 4 ++-- src/Umbraco.Core/app.config | 2 +- src/Umbraco.Core/packages.config | 2 +- src/Umbraco.Tests/App.config | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 4 ++-- src/Umbraco.Tests/packages.config | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- src/Umbraco.Web.UI/packages.config | 2 +- src/Umbraco.Web.UI/web.Template.Debug.config | 9 ++++++++- src/Umbraco.Web.UI/web.Template.config | 6 +++--- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- src/Umbraco.Web/app.config | 2 +- src/Umbraco.Web/packages.config | 2 +- src/UmbracoExamine/app.config | 2 +- src/umbraco.MacroEngines/app.config | 2 +- src/umbraco.MacroEngines/packages.config | 2 +- src/umbraco.MacroEngines/umbraco.MacroEngines.csproj | 4 ++-- src/umbraco.businesslogic/app.config | 2 +- src/umbraco.businesslogic/packages.config | 2 +- src/umbraco.businesslogic/umbraco.businesslogic.csproj | 4 ++-- src/umbraco.cms/app.config | 2 +- src/umbraco.controls/app.config | 2 +- src/umbraco.datalayer/app.config | 2 +- src/umbraco.editorControls/app.config | 2 +- src/umbraco.providers/app.config | 2 +- 26 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/SQLCE4Umbraco/app.config b/src/SQLCE4Umbraco/app.config index 53f3b4c80b..8f828418f3 100644 --- a/src/SQLCE4Umbraco/app.config +++ b/src/SQLCE4Umbraco/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 8abdd10f9f..bc272d351e 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -99,9 +99,9 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Core/app.config b/src/Umbraco.Core/app.config index 53f3b4c80b..8f828418f3 100644 --- a/src/Umbraco.Core/app.config +++ b/src/Umbraco.Core/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index 1d5de7749b..d717c88286 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 45a43631f7..3d35ae5c93 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -100,7 +100,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 2ae4b72a8c..18b9b8d006 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -132,9 +132,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config index 4e89abb9a1..58d314c3b1 100644 --- a/src/Umbraco.Tests/packages.config +++ b/src/Umbraco.Tests/packages.config @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 28f8183a7e..5de747c1fb 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -230,9 +230,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll True - - ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + True + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 3c1927aac8..4a754f6758 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -9,7 +9,7 @@ - + diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index d5901a5c5e..1aecc61f45 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -132,7 +132,14 @@ xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.Mvc']])" /> - + + + + + + + - + - - + + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 5c3c521b16..08cf22ecd6 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -195,9 +195,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Web/app.config b/src/Umbraco.Web/app.config index 105ebc53f3..957569042f 100644 --- a/src/Umbraco.Web/app.config +++ b/src/Umbraco.Web/app.config @@ -29,7 +29,7 @@ - + diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index 3fee35e677..315d780852 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -6,7 +6,7 @@ - + diff --git a/src/UmbracoExamine/app.config b/src/UmbracoExamine/app.config index 3a3e923d5b..b77bae14a4 100644 --- a/src/UmbracoExamine/app.config +++ b/src/UmbracoExamine/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.MacroEngines/app.config b/src/umbraco.MacroEngines/app.config index d9a8025f65..900c3903d5 100644 --- a/src/umbraco.MacroEngines/app.config +++ b/src/umbraco.MacroEngines/app.config @@ -16,7 +16,7 @@ - + diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config index 24fd666515..9951ba7e01 100644 --- a/src/umbraco.MacroEngines/packages.config +++ b/src/umbraco.MacroEngines/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj index 59e5e4b4c6..a34198b5ce 100644 --- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj +++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj @@ -89,9 +89,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.4.0.30506.0\lib\net40\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/umbraco.businesslogic/app.config b/src/umbraco.businesslogic/app.config index 3a3e923d5b..b77bae14a4 100644 --- a/src/umbraco.businesslogic/app.config +++ b/src/umbraco.businesslogic/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.businesslogic/packages.config b/src/umbraco.businesslogic/packages.config index 63fd1fb7c3..59350953ba 100644 --- a/src/umbraco.businesslogic/packages.config +++ b/src/umbraco.businesslogic/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/umbraco.businesslogic/umbraco.businesslogic.csproj b/src/umbraco.businesslogic/umbraco.businesslogic.csproj index 8f1a26c8fb..d74e2dc92e 100644 --- a/src/umbraco.businesslogic/umbraco.businesslogic.csproj +++ b/src/umbraco.businesslogic/umbraco.businesslogic.csproj @@ -136,9 +136,9 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/umbraco.cms/app.config b/src/umbraco.cms/app.config index 3a3e923d5b..b77bae14a4 100644 --- a/src/umbraco.cms/app.config +++ b/src/umbraco.cms/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.controls/app.config b/src/umbraco.controls/app.config index 3a3e923d5b..b77bae14a4 100644 --- a/src/umbraco.controls/app.config +++ b/src/umbraco.controls/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.datalayer/app.config b/src/umbraco.datalayer/app.config index 53f3b4c80b..8f828418f3 100644 --- a/src/umbraco.datalayer/app.config +++ b/src/umbraco.datalayer/app.config @@ -8,7 +8,7 @@ - + diff --git a/src/umbraco.editorControls/app.config b/src/umbraco.editorControls/app.config index baa57f9ff7..734aeed7b8 100644 --- a/src/umbraco.editorControls/app.config +++ b/src/umbraco.editorControls/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.providers/app.config b/src/umbraco.providers/app.config index 3a3e923d5b..b77bae14a4 100644 --- a/src/umbraco.providers/app.config +++ b/src/umbraco.providers/app.config @@ -4,7 +4,7 @@ - + From d94b334375b7b1ba5fffba699e4eeb89418f147f Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 11 May 2015 12:22:56 +1000 Subject: [PATCH 40/51] Moves login logging to the provider level --- src/Umbraco.Core/HttpContextExtensions.cs | 45 +++++++++++++++++ .../Security/MembershipProviderBase.cs | 11 +++++ src/Umbraco.Core/Umbraco.Core.csproj | 1 + .../Editors/AuthenticationController.cs | 21 +------- .../Providers/UmbracoMembershipProvider.cs | 48 +++++++++++++++++-- .../UsersMembershipProvider.cs | 27 ++++++++++- 6 files changed, 128 insertions(+), 25 deletions(-) create mode 100644 src/Umbraco.Core/HttpContextExtensions.cs diff --git a/src/Umbraco.Core/HttpContextExtensions.cs b/src/Umbraco.Core/HttpContextExtensions.cs new file mode 100644 index 0000000000..b4e420dc42 --- /dev/null +++ b/src/Umbraco.Core/HttpContextExtensions.cs @@ -0,0 +1,45 @@ +using System.Web; + +namespace Umbraco.Core +{ + public static class HttpContextExtensions + { + public static string GetCurrentRequestIpAddress(this HttpContextBase httpContext) + { + if (httpContext == null) + { + return "Unknown, httpContext is null"; + } + if (httpContext.Request == null) + { + return "Unknown, httpContext.Request is null"; + } + if (httpContext.Request.ServerVariables == null) + { + return "Unknown, httpContext.Request.ServerVariables is null"; + } + + // From: http://stackoverflow.com/a/740431/5018 + + try + { + var ipAddress = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; + + if (string.IsNullOrEmpty(ipAddress)) + return httpContext.Request.ServerVariables["REMOTE_ADDR"]; + + var addresses = ipAddress.Split(','); + if (addresses.Length != 0) + return addresses[0]; + + return httpContext.Request.ServerVariables["REMOTE_ADDR"]; + } + catch (System.Exception ex) + { + //This try catch is to just always ensure that no matter what we're not getting any exceptions caused since + // that would cause people to not be able to login + return string.Format("Unknown, exception occurred trying to resolve IP {0}", ex); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Security/MembershipProviderBase.cs b/src/Umbraco.Core/Security/MembershipProviderBase.cs index ebcd967cc2..d12b9a952e 100644 --- a/src/Umbraco.Core/Security/MembershipProviderBase.cs +++ b/src/Umbraco.Core/Security/MembershipProviderBase.cs @@ -4,6 +4,7 @@ using System.Configuration.Provider; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; +using System.Web; using System.Web.Configuration; using System.Web.Hosting; using System.Web.Security; @@ -893,5 +894,15 @@ namespace Umbraco.Core.Security return sb.ToString(); } + /// + /// Returns the current request IP address for logging if there is one + /// + /// + protected string GetCurrentRequestIpAddress() + { + var httpContext = HttpContext.Current == null ? (HttpContextBase) null : new HttpContextWrapper(HttpContext.Current); + return httpContext.GetCurrentRequestIpAddress(); + } + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index bc272d351e..070090d8c7 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -313,6 +313,7 @@ + diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index 378306fdb4..43236226a1 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -107,8 +107,6 @@ namespace Umbraco.Web.Editors if (http.Success == false) throw new InvalidOperationException("This method requires that an HttpContext be active"); - var ipAddress = GetIPAddress(http.Result); - if (UmbracoContext.Security.ValidateBackOfficeCredentials(loginModel.Username, loginModel.Password)) { var user = Security.GetBackOfficeUser(loginModel.Username); @@ -121,16 +119,13 @@ namespace Umbraco.Web.Editors //set their remaining seconds result.SecondsUntilTimeout = ticket.GetRemainingAuthSeconds(); - LogHelper.Info(string.Format("Login attempt succeeded for username {0} from IP address {1}", loginModel.Username, ipAddress)); return result; } //return BadRequest (400), we don't want to return a 401 because that get's intercepted // by our angular helper because it thinks that we need to re-perform the request once we are // authorized and we don't want to return a 403 because angular will show a warning msg indicating - // that the user doesn't have access to perform this function, we just want to return a normal invalid msg. - - LogHelper.Info(string.Format("Login attempt failed for username {0} from IP address {1}", loginModel.Username, ipAddress)); + // that the user doesn't have access to perform this function, we just want to return a normal invalid msg. throw new HttpResponseException(HttpStatusCode.BadRequest); } @@ -147,19 +142,5 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(HttpStatusCode.OK); } - // From: http://stackoverflow.com/a/740431/5018 - protected string GetIPAddress(HttpContextBase httpContext) - { - var ipAddress = httpContext.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; - - if (string.IsNullOrEmpty(ipAddress)) - return httpContext.Request.ServerVariables["REMOTE_ADDR"]; - - var addresses = ipAddress.Split(','); - if (addresses.Length != 0) - return addresses[0]; - - return httpContext.Request.ServerVariables["REMOTE_ADDR"]; - } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs index 16641e5f91..65f90d8127 100644 --- a/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs +++ b/src/Umbraco.Web/Security/Providers/UmbracoMembershipProvider.cs @@ -511,16 +511,35 @@ namespace Umbraco.Web.Security.Providers { var member = MemberService.GetByUsername(username); - if (member == null) return false; + if (member == null) + { + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}, the user does not exist", + username, + GetCurrentRequestIpAddress())); + + return false; + } if (member.IsApproved == false) { - LogHelper.Info>("Cannot validate member " + username + " because they are not approved"); + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}, the user is not approved", + username, + GetCurrentRequestIpAddress())); + return false; } if (member.IsLockedOut) { - LogHelper.Info>("Cannot validate member " + username + " because they are currently locked out"); + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}, the user is locked", + username, + GetCurrentRequestIpAddress())); + return false; } @@ -538,18 +557,39 @@ namespace Umbraco.Web.Security.Providers { member.IsLockedOut = true; member.LastLockoutDate = DateTime.Now; - LogHelper.Info>("Member " + username + " is now locked out, max invalid password attempts exceeded"); + + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}, the user is now locked out, max invalid password attempts exceeded", + username, + GetCurrentRequestIpAddress())); + } + else + { + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}", + username, + GetCurrentRequestIpAddress())); } } else { member.FailedPasswordAttempts = 0; member.LastLoginDate = DateTime.Now; + + LogHelper.Info( + string.Format( + "Login attempt succeeded for username {0} from IP address {1}", + username, + GetCurrentRequestIpAddress())); } //don't raise events for this! It just sets the member dates, if we do raise events this will // cause all distributed cache to execute - which will clear out some caches we don't want. // http://issues.umbraco.org/issue/U4-3451 + //TODO: In v8 we aren't going to have an overload to disable events, so we'll need to make a different method + // for this type of thing (i.e. UpdateLastLogin or similar). MemberService.Save(member, false); return authenticated; diff --git a/src/umbraco.providers/UsersMembershipProvider.cs b/src/umbraco.providers/UsersMembershipProvider.cs index df190a8ac0..93f5327cbb 100644 --- a/src/umbraco.providers/UsersMembershipProvider.cs +++ b/src/umbraco.providers/UsersMembershipProvider.cs @@ -9,6 +9,8 @@ using umbraco.BusinessLogic; using System.Web.Util; using System.Configuration.Provider; using System.Linq; +using Umbraco.Core.Logging; + #endregion namespace umbraco.providers @@ -491,10 +493,33 @@ namespace umbraco.providers { if (user.Disabled) { + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}, the user is locked", + username, + GetCurrentRequestIpAddress())); + return false; } - return CheckPassword(password, user.Password); + var result = CheckPassword(password, user.Password); + if (result == false) + { + LogHelper.Info( + string.Format( + "Login attempt failed for username {0} from IP address {1}", + username, + GetCurrentRequestIpAddress())); + } + else + { + LogHelper.Info( + string.Format( + "Login attempt succeeded for username {0} from IP address {1}", + username, + GetCurrentRequestIpAddress())); + } + return result; } } return false; From d2deaf0375392cde8a103d7841e7aa68190c7cd5 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 11 May 2015 12:43:45 +1000 Subject: [PATCH 41/51] Fixes MVC references and updates to 4.0.0.1 --- src/Umbraco.Tests/App.config | 2 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 4 ++-- src/Umbraco.Tests/packages.config | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- src/Umbraco.Web.UI/packages.config | 2 +- src/Umbraco.Web.UI/web.Template.Debug.config | 2 +- src/Umbraco.Web.UI/web.Template.config | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- src/Umbraco.Web/app.config | 2 +- src/UmbracoExamine/app.config | 2 +- src/umbraco.MacroEngines/app.config | 2 +- src/umbraco.MacroEngines/packages.config | 2 +- src/umbraco.MacroEngines/umbraco.MacroEngines.csproj | 4 ++-- src/umbraco.businesslogic/app.config | 2 +- src/umbraco.businesslogic/packages.config | 2 +- src/umbraco.businesslogic/umbraco.businesslogic.csproj | 4 ++-- src/umbraco.cms/app.config | 2 +- src/umbraco.controls/app.config | 2 +- src/umbraco.editorControls/app.config | 2 +- src/umbraco.providers/app.config | 2 +- 20 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index f1917d16c0..d64d47b2ee 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -100,7 +100,7 @@ - + diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index f60e3de26f..9190056d66 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -135,9 +135,9 @@ False ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config index a70db56875..9dc85b4dcb 100644 --- a/src/Umbraco.Tests/packages.config +++ b/src/Umbraco.Tests/packages.config @@ -5,7 +5,7 @@ - + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 13312a0529..837ee9f376 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -263,9 +263,9 @@ ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll True - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 9f2dc64937..0aad02b3d6 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -11,7 +11,7 @@ - + diff --git a/src/Umbraco.Web.UI/web.Template.Debug.config b/src/Umbraco.Web.UI/web.Template.Debug.config index 38877c8d54..2e0745db90 100644 --- a/src/Umbraco.Web.UI/web.Template.Debug.config +++ b/src/Umbraco.Web.UI/web.Template.Debug.config @@ -133,7 +133,7 @@ xdt:Locator="Condition(_defaultNamespace:assemblyIdentity[@name='System.Web.Mvc']])" /> - + - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 22283d0b64..af8b4fc71a 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -230,9 +230,9 @@ False ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/Umbraco.Web/app.config b/src/Umbraco.Web/app.config index 71898fd12e..548dde0987 100644 --- a/src/Umbraco.Web/app.config +++ b/src/Umbraco.Web/app.config @@ -29,7 +29,7 @@ - + diff --git a/src/UmbracoExamine/app.config b/src/UmbracoExamine/app.config index 4022c25600..0f2278a158 100644 --- a/src/UmbracoExamine/app.config +++ b/src/UmbracoExamine/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.MacroEngines/app.config b/src/umbraco.MacroEngines/app.config index cabc84546e..6cd2ad76f2 100644 --- a/src/umbraco.MacroEngines/app.config +++ b/src/umbraco.MacroEngines/app.config @@ -16,7 +16,7 @@ - + diff --git a/src/umbraco.MacroEngines/packages.config b/src/umbraco.MacroEngines/packages.config index d6a893c69f..ac2cfc7e95 100644 --- a/src/umbraco.MacroEngines/packages.config +++ b/src/umbraco.MacroEngines/packages.config @@ -3,7 +3,7 @@ - + diff --git a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj index f6880d7c3a..347a016a96 100644 --- a/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj +++ b/src/umbraco.MacroEngines/umbraco.MacroEngines.csproj @@ -92,9 +92,9 @@ False ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/umbraco.businesslogic/app.config b/src/umbraco.businesslogic/app.config index 4022c25600..0f2278a158 100644 --- a/src/umbraco.businesslogic/app.config +++ b/src/umbraco.businesslogic/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.businesslogic/packages.config b/src/umbraco.businesslogic/packages.config index b1c4140b1a..f07166e262 100644 --- a/src/umbraco.businesslogic/packages.config +++ b/src/umbraco.businesslogic/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/umbraco.businesslogic/umbraco.businesslogic.csproj b/src/umbraco.businesslogic/umbraco.businesslogic.csproj index 970bc1ef9c..5ad8cc72d0 100644 --- a/src/umbraco.businesslogic/umbraco.businesslogic.csproj +++ b/src/umbraco.businesslogic/umbraco.businesslogic.csproj @@ -143,9 +143,9 @@ True ..\packages\Microsoft.AspNet.WebPages.2.0.30506.0\lib\net40\System.Web.Helpers.dll - + True - ..\packages\Microsoft.AspNet.Mvc.4.0.30506.0\lib\net40\System.Web.Mvc.dll + ..\packages\Microsoft.AspNet.Mvc.4.0.40804.0\lib\net40\System.Web.Mvc.dll True diff --git a/src/umbraco.cms/app.config b/src/umbraco.cms/app.config index 4022c25600..0f2278a158 100644 --- a/src/umbraco.cms/app.config +++ b/src/umbraco.cms/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.controls/app.config b/src/umbraco.controls/app.config index 4022c25600..0f2278a158 100644 --- a/src/umbraco.controls/app.config +++ b/src/umbraco.controls/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.editorControls/app.config b/src/umbraco.editorControls/app.config index 68046c3af5..0b61939c20 100644 --- a/src/umbraco.editorControls/app.config +++ b/src/umbraco.editorControls/app.config @@ -4,7 +4,7 @@ - + diff --git a/src/umbraco.providers/app.config b/src/umbraco.providers/app.config index 4022c25600..0f2278a158 100644 --- a/src/umbraco.providers/app.config +++ b/src/umbraco.providers/app.config @@ -4,7 +4,7 @@ - + From d6699ab3b34623239c049db6b2237b295b26bace Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 11 May 2015 16:18:35 +1000 Subject: [PATCH 42/51] Fixes: U4-6102 After renaming Grid row configurations all data is lost, also ensures that all events are unsubscribed on destroy --- .../validation/valformmanager.directive.js | 18 ++++++----- .../validation/valpropertymsg.directive.js | 23 ++++++++++---- .../validation/valtogglemsg.directive.js | 15 +++++---- .../src/common/services/dialog.service.js | 7 +++++ .../prevalueeditors/mediapicker.controller.js | 7 ++++- .../prevalueeditors/treepicker.controller.js | 7 ++++- .../prevalueeditors/treesource.controller.js | 7 ++++- .../changepassword.controller.js | 19 +++++++++--- .../contentpicker/contentpicker.controller.js | 7 ++++- .../grid/dialogs/rowdeleteconfirm.html | 31 +++++++++++++++++++ .../grid/grid.prevalues.controller.js | 26 ++++++++++++++-- .../macrocontainer.controller.js | 7 ++++- .../membergrouppicker.controller.js | 7 ++++- .../memberpicker/memberpicker.controller.js | 7 ++++- .../rte/rte.prevalues.controller.js | 8 +++-- 15 files changed, 159 insertions(+), 37 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowdeleteconfirm.html diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js index 1bd4d409e7..506bba8990 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valformmanager.directive.js @@ -48,27 +48,29 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not element.addClass(className); } + var unsubscribe = []; + //listen for the forms saving event - scope.$on(savingEventName, function (ev, args) { + unsubscribe.push(scope.$on(savingEventName, function(ev, args) { element.addClass(className); //set the flag so we can check to see if we should display the error. isSavingNewItem = $routeParams.create; - }); + })); //listen for the forms saved event - scope.$on(savedEvent, function (ev, args) { + unsubscribe.push(scope.$on(savedEvent, function(ev, args) { //remove validation class element.removeClass(className); //clear form state as at this point we retrieve new data from the server //and all validation will have cleared at this point formCtrl.$setPristine(); - }); + })); //This handles the 'unsaved changes' dialog which is triggered when a route is attempting to be changed but // the form has pending changes - var locationEvent = $rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) { + unsubscribe.push($rootScope.$on('$locationChangeStart', function(event, nextLocation, currentLocation) { if (!formCtrl.$dirty || isSavingNewItem) { return; } @@ -91,11 +93,11 @@ function valFormManager(serverValidationManager, $rootScope, $log, $timeout, not eventsService.emit("valFormManager.pendingChanges", true); } - }); + })); //Ensure to remove the event handler when this instance is destroyted scope.$on('$destroy', function() { - if(locationEvent){ - locationEvent(); + for (var u in unsubscribe) { + unsubscribe[u](); } }); diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js index a8d546bc36..eba308d830 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valpropertymsg.directive.js @@ -96,8 +96,10 @@ function valPropertyMsg(serverValidationManager) { //create properties on our custom scope so we can use it in our template scope.errorMsg = ""; + var unsubscribe = []; + //listen for form error changes - scope.$on("valStatusChanged", function (evt, args) { + unsubscribe.push(scope.$on("valStatusChanged", function(evt, args) { if (args.form.$invalid) { //first we need to check if the valPropertyMsg validity is invalid @@ -123,10 +125,10 @@ function valPropertyMsg(serverValidationManager) { hasError = false; scope.errorMsg = ""; } - }, true); + }, true)); //listen for the forms saving event - scope.$on("formSubmitting", function (ev, args) { + unsubscribe.push(scope.$on("formSubmitting", function(ev, args) { showValidation = true; if (hasError && scope.errorMsg === "") { scope.errorMsg = getErrorMsg(); @@ -135,15 +137,15 @@ function valPropertyMsg(serverValidationManager) { scope.errorMsg = ""; stopWatch(); } - }); + })); //listen for the forms saved event - scope.$on("formSubmitted", function (ev, args) { + unsubscribe.push(scope.$on("formSubmitted", function(ev, args) { showValidation = false; scope.errorMsg = ""; formCtrl.$setValidity('valPropertyMsg', true); stopWatch(); - }); + })); //listen for server validation changes // NOTE: we pass in "" in order to listen for all validation changes to the content property, not for @@ -179,7 +181,16 @@ function valPropertyMsg(serverValidationManager) { serverValidationManager.unsubscribe(scope.property.alias, ""); }); } + + //when the scope is disposed we need to unsubscribe + scope.$on('$destroy', function () { + for (var u in unsubscribe) { + unsubscribe[u](); + } + }); } + + }; } angular.module('umbraco.directives.validation').directive("valPropertyMsg", valPropertyMsg); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js index cdcfbcfe2a..43792a708a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js +++ b/src/Umbraco.Web.UI.Client/src/common/directives/validation/valtogglemsg.directive.js @@ -43,8 +43,10 @@ function valToggleMsg(serverValidationManager) { } }); + var unsubscribe = []; + //listen for the saving event (the result is a callback method which is called to unsubscribe) - var unsubscribeSaving = scope.$on("formSubmitting", function (ev, args) { + unsubscribe.push(scope.$on("formSubmitting", function(ev, args) { showValidation = true; if (formCtrl[attr.valMsgFor].$error[attr.valToggleMsg]) { element.show(); @@ -56,20 +58,21 @@ function valToggleMsg(serverValidationManager) { else { element.hide(); } - }); + })); //listen for the saved event (the result is a callback method which is called to unsubscribe) - var unsubscribeSaved = scope.$on("formSubmitted", function (ev, args) { + unsubscribe.push(scope.$on("formSubmitted", function(ev, args) { showValidation = false; element.hide(); - }); + })); //when the element is disposed we need to unsubscribe! // NOTE: this is very important otherwise if this directive is part of a modal, the listener still exists because the dom // element might still be there even after the modal has been hidden. element.bind('$destroy', function () { - unsubscribeSaving(); - unsubscribeSaved(); + for (var u in unsubscribe) { + unsubscribe[u](); + } }); } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js index 5746fd022c..e79b6f8f78 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/dialog.service.js @@ -537,6 +537,13 @@ angular.module('umbraco.services') template: 'views/common/dialogs/ysod.html', show: true }); + }, + + confirmDialog: function (ysodError) { + + options.template = 'views/common/dialogs/confirm.html'; + options.show = true; + return openDialog(options); } }; }); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js index 664c246b14..baf7ada8a8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/mediapicker.controller.js @@ -49,13 +49,18 @@ function mediaPickerController($scope, dialogService, entityResource, $log, icon } }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var currIds = _.map($scope.renderModel, function (i) { return i.id; }); $scope.model.value = trim(currIds.join(), ","); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + //load media data var modelIds = $scope.model.value ? $scope.model.value.split(',') : []; entityResource.getByIds(modelIds, dialogOptions.entityType).then(function (data) { diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js index 5dc615b449..7bb02ba751 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treepicker.controller.js @@ -58,10 +58,15 @@ angular.module('umbraco') }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { $scope.model.value = trim($scope.ids.join(), ","); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + function trim(str, chr) { var rgxtrim = (!chr) ? new RegExp('^\\s+|\\s+$', 'g') : new RegExp('^'+chr+'+|'+chr+'+$', 'g'); return str.replace(rgxtrim, ''); diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js index 1797bf1de1..087447b184 100644 --- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/treesource.controller.js @@ -43,13 +43,18 @@ angular.module('umbraco') //we always need to ensure we dont submit anything broken - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { if($scope.model.value.type === "member"){ $scope.model.value.id = -1; $scope.model.value.query = ""; } }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + function populate(item){ $scope.clear(); item.icon = iconHelper.convertFromLegacyIcon(item.icon); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js index 8ae6b137d6..9c322f3f5d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/changepassword/changepassword.controller.js @@ -91,15 +91,17 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.ChangePasswordCont //set model to null $scope.model.value = null; }; - + + var unsubscribe = []; + //listen for the saved event, when that occurs we'll //change to changing = false; - $scope.$on("formSubmitted", function () { + unsubscribe.push($scope.$on("formSubmitted", function() { if ($scope.model.config.disableToggle === false) { $scope.changing = false; - } - }); - $scope.$on("formSubmitting", function() { + } + })); + unsubscribe.push($scope.$on("formSubmitting", function() { //if there was a previously generated password displaying, clear it if ($scope.changing && $scope.model.value) { $scope.model.value.generatedPassword = null; @@ -108,6 +110,13 @@ angular.module("umbraco").controller("Umbraco.PropertyEditors.ChangePasswordCont //we are not changing, so the model needs to be null $scope.model.value = null; } + })); + + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + for (var u in unsubscribe) { + unsubscribe[u](); + } }); $scope.showReset = function() { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js index 8847db455b..9c37a9a2a9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js @@ -158,13 +158,18 @@ function contentPickerController($scope, dialogService, entityResource, editorSt $scope.renderModel = []; }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var currIds = _.map($scope.renderModel, function (i) { return i.id; }); $scope.model.value = trim(currIds.join(), ","); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + //load current data var modelIds = $scope.model.value ? $scope.model.value.split(',') : []; entityResource.getByIds(modelIds, entityType).then(function (data) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowdeleteconfirm.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowdeleteconfirm.html new file mode 100644 index 0000000000..b22b6baf83 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowdeleteconfirm.html @@ -0,0 +1,31 @@ +
    + + + +
    \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js index 82b36697d8..229a7992f5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/grid.prevalues.controller.js @@ -127,9 +127,24 @@ angular.module("umbraco") ); }; + //var rowDeletesPending = false; + $scope.deleteLayout = function (index) { + //rowDeletesPending = true; - $scope.deleteLayout = function(index){ - $scope.model.value.layouts.splice(index, 1); + //show ok/cancel dialog + var confirmDialog = dialogService.open( + { + template: "views/propertyEditors/grid/dialogs/rowdeleteconfirm.html", + show: true, + callback: function() { + $scope.model.value.layouts.splice(index, 1); + }, + dialogData: { + rowName: $scope.model.value.layouts[index].name + } + } + ); + }; @@ -216,7 +231,7 @@ angular.module("umbraco") /**************** Clean up *****************/ - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var ts = $scope.model.value.templates; var ls = $scope.model.value.layouts; @@ -237,4 +252,9 @@ angular.module("umbraco") }); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + }); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/macrocontainer/macrocontainer.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/macrocontainer/macrocontainer.controller.js index 1c1e94601b..14cf1592e6 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/macrocontainer/macrocontainer.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/macrocontainer/macrocontainer.controller.js @@ -85,7 +85,7 @@ angular.module('umbraco') $scope.renderModel = []; }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var syntax = []; angular.forEach($scope.renderModel, function(value, key){ syntax.push(value.syntax); @@ -94,6 +94,11 @@ angular.module('umbraco') $scope.model.value = syntax.join(""); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + function trim(str, chr) { var rgxtrim = (!chr) ? new RegExp('^\\s+|\\s+$', 'g') : new RegExp('^'+chr+'+|'+chr+'+$', 'g'); diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js index 92aa89bc6e..1c801cddb3 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/membergrouppicker/membergrouppicker.controller.js @@ -65,13 +65,18 @@ function memberGroupPicker($scope, dialogService){ $scope.renderModel = []; }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var currIds = _.map($scope.renderModel, function (i) { return i.id; }); $scope.model.value = trim(currIds.join(), ","); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + } angular.module('umbraco').controller("Umbraco.PropertyEditors.MemberGroupPickerController", memberGroupPicker); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/memberpicker/memberpicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/memberpicker/memberpicker.controller.js index bdbeae9bff..7d5ad22fb8 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/memberpicker/memberpicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/memberpicker/memberpicker.controller.js @@ -60,13 +60,18 @@ function memberPickerController($scope, dialogService, entityResource, $log, ico $scope.renderModel = []; }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var currIds = _.map($scope.renderModel, function (i) { return i.id; }); $scope.model.value = trim(currIds.join(), ","); }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + //load member data var modelIds = $scope.model.value ? $scope.model.value.split(',') : []; entityResource.getByIds(modelIds, "Member").then(function (data) { diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js index 566fff2553..c815bc0c5e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.prevalues.controller.js @@ -58,12 +58,16 @@ angular.module("umbraco").controller("Umbraco.PrevalueEditors.RteController", } }; - $scope.$on("formSubmitting", function (ev, args) { + var unsubscribe = $scope.$on("formSubmitting", function (ev, args) { var commands = _.where($scope.tinyMceConfig.commands, {selected: true}); $scope.model.value.toolbar = _.pluck(commands, "frontEndCommand"); - }); + //when the scope is destroyed we need to unsubscribe + $scope.$on('$destroy', function () { + unsubscribe(); + }); + }); From 795de94a5f1f146e4e7b55aad6f6ce53b2006c85 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 11 May 2015 18:46:26 +1000 Subject: [PATCH 43/51] Fixes: U4-6102 After renaming Grid row configurations all data is lost for renames. So now we have warnings for both deletes and renames. --- .../grid/dialogs/rowconfig.controller.js | 152 ++++++++++-------- .../grid/dialogs/rowconfig.html | 12 +- .../grid/dialogs/rowdeleteconfirm.html | 27 ++-- 3 files changed, 107 insertions(+), 84 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.controller.js index e8b6c02271..70f9951de5 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.controller.js @@ -1,79 +1,97 @@ -angular.module("umbraco") - .controller("Umbraco.PropertyEditors.GridPrevalueEditor.RowConfigController", - function ($scope) { +function RowConfigController($scope) { + + $scope.currentRow = angular.copy($scope.dialogOptions.currentRow); + $scope.editors = $scope.dialogOptions.editors; + $scope.columns = $scope.dialogOptions.columns; - $scope.currentRow = $scope.dialogOptions.currentRow; - $scope.editors = $scope.dialogOptions.editors; - $scope.columns = $scope.dialogOptions.columns; + $scope.scaleUp = function(section, max, overflow) { + var add = 1; + if (overflow !== true) { + add = (max > 1) ? 1 : max; + } + //var add = (max > 1) ? 1 : max; + section.grid = section.grid + add; + }; - $scope.scaleUp = function(section, max, overflow){ - var add = 1; - if(overflow !== true){ - add = (max > 1) ? 1 : max; - } - //var add = (max > 1) ? 1 : max; - section.grid = section.grid+add; - }; + $scope.scaleDown = function(section) { + var remove = (section.grid > 1) ? 1 : section.grid; + section.grid = section.grid - remove; + }; - $scope.scaleDown = function(section){ - var remove = (section.grid > 1) ? 1 : section.grid; - section.grid = section.grid-remove; - }; + $scope.percentage = function(spans) { + return ((spans / $scope.columns) * 100).toFixed(1); + }; - $scope.percentage = function(spans){ - return ((spans / $scope.columns) * 100).toFixed(1); - }; - - $scope.toggleCollection = function(collection, toggle){ - if(toggle){ - collection = []; - }else{ - delete collection; - } - }; + $scope.toggleCollection = function(collection, toggle) { + if (toggle) { + collection = []; + } + else { + delete collection; + } + }; - /**************** - area - *****************/ - $scope.configureCell = function(cell, row){ - if($scope.currentCell && $scope.currentCell=== cell){ - delete $scope.currentCell; - }else{ - if(cell === undefined){ - var available = $scope.availableRowSpace; - var space = 4; + /**************** + area + *****************/ + $scope.configureCell = function(cell, row) { + if ($scope.currentCell && $scope.currentCell === cell) { + delete $scope.currentCell; + } + else { + if (cell === undefined) { + var available = $scope.availableRowSpace; + var space = 4; - if(available < 4 && available > 0){ - space = available; - } - - cell = { - grid: space - }; - - row.areas.push(cell); - } - $scope.currentCell = cell; + if (available < 4 && available > 0) { + space = available; } - }; - $scope.deleteArea = function(index){ - $scope.currentRow.areas.splice(index, 1); - }; - $scope.closeArea = function(){ - $scope.currentCell = undefined; - }; + cell = { + grid: space + }; + row.areas.push(cell); + } + $scope.currentCell = cell; + } + }; - $scope.$watch("currentRow", function(row){ - if(row){ - var total = 0; - _.forEach(row.areas, function(area){ - total = (total + area.grid); - }); + $scope.deleteArea = function(index) { + $scope.currentRow.areas.splice(index, 1); + }; + $scope.closeArea = function() { + $scope.currentCell = undefined; + }; - $scope.availableRowSpace = $scope.columns - total; - } - }, true); - }); \ No newline at end of file + $scope.nameChanged = false; + var originalName = $scope.currentRow.name; + $scope.$watch("currentRow", function(row) { + if (row) { + + var total = 0; + _.forEach(row.areas, function(area) { + total = (total + area.grid); + }); + + $scope.availableRowSpace = $scope.columns - total; + + if (originalName) { + if (originalName != row.name) { + $scope.nameChanged = true; + } + else { + $scope.nameChanged = false; + } + } + } + }, true); + + $scope.complete = function () { + angular.extend($scope.dialogOptions.currentRow, $scope.currentRow); + $scope.close(); + } +} + +angular.module("umbraco").controller("Umbraco.PropertyEditors.GridPrevalueEditor.RowConfigController", RowConfigController); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.html index 07aa2d2fbd..63e250645f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.html +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/grid/dialogs/rowconfig.html @@ -1,11 +1,17 @@